관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Undo, 되돌리기 구현 방법 (UndoManager) 본문

iOS 응용 (swift)

[iOS - swift] Undo, 되돌리기 구현 방법 (UndoManager)

jake-kim 2021. 9. 4. 18:02

UndoManager

  • undo, redo에 필요한 명령어들이 있는 클래스

  • registerUndo(withTarget:handler:): closure로 single undo명령어를 구현
    • target: undo 명령어가 동작할 타겟 - 내부적으로 unowned reference를 사용하여 retain cycle을 방지
      target이 필요한 이유: undo를 실행할 때 self로 실행시킬 대상을 self로 구분하여 추후에 호출하는 곳을 확인하기 위함
    • handler: undo 명령어가 실행될때 동작

ex) UndoManager 사용하여 배열에 삭제한 값 되돌리는 방법

  • undoManager와 undo 시킬 배열 정의
var manager = UndoManager()
var bouquetSelection: NSMutableArray = ["lilac", "lavender"]
  • 배열에 특정 값 삭제, 삭제한 값을 되돌리는 작업을 undo에 등록
// retain cycle 주의
func pull(flower: String) {
    bouquetSelection.remove(flower)
    manager.registerUndo(withTarget: bouquetSelection) { $0.add(flower) }
}
  • undo 실행
pull(flower: "lilac")
print(bouquetSelection)// ["lavender"]
manager.undo()
print(bouquetSelection) // ["lavender", "lilac"]

UIViewController에 내장된 undoManager를 통해 undo 구현

  • UIViewController에 내장된 undoManager 사용 방법
class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    var count = 0 {
        didSet {
            label.text = String(count)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func didTapAddButton(_ sender: Any) {
        let beforeCount = count
        count += 1
        undoManager?.registerUndo(withTarget: self, handler: { [weak self] selfTarget in
            self?.count = beforeCount
        })
    }

    @IBAction func didTapSubtractButton(_ sender: Any) {
        let beforeCount = count
        count -= 1
        undoManager?.registerUndo(withTarget: self, handler: { [weak self] selfTarget in
            self?.count = beforeCount
        })
    }

    @IBAction func didTapUndoButton(_ sender: Any) {
        undoManager?.undo()
    }
}
  • undo가 가능한지 확인 방법
undoManager?.canUndo

- 참고

* registerUndo(withTarget:handler:): https://developer.apple.com/documentation/foundation/undomanager/2427208-registerundo

* UndoManager: https://developer.apple.com/documentation/foundation/undomanager* 

Comments