TIL
🌱 난 오늘 무엇을 공부했을까?
- 실행 취소 및 다시 실행을 가능하게 하는 범용 작업 레코더입니다.
📍 Declaration
class UndoManager : NSObject
📍 Overview
- 실행 취소 작업 등록에 설명된 방법 중 하나를 호출하여 실행 취소 작업을 등록합니다.
- 변경 중인 객체(또는 해당 객체의 소유자)의 이름을 지정하고 해당 상태를 되돌리기 위한 클로저, 메서드 또는 호출을 제공합니다.
실행 취소 작업을 등록한 후 실행 취소 관리자에서 undo()를 호출하여 마지막 실행 취소 작업의 상태로 되돌릴 수 있습니다.
- 작업을 실행 취소할 때 UndoManager는 사용자가 redo()를 자동으로 호출할 수 있도록 되돌린 작업을 저장합니다.
UndoManager는 일반적으로 UI 상호 작용이 있는 앱에서 사용됩니다.
예를 들어 UIKit은 텍스트 보기 개체에서 실행 취소 및 다시 실행을 구현하므로 응답자 체인을 따라 개체에서 작업을 쉽게 실행 취소하고 다시 실행할 수 있습니다.
- UndoManager는 또한 여러 종류의 작업을 실행 취소하고 다시 실행하는 데 사용할 수 있는 범용 상태 관리자 역할도 합니다.
- 예를 들어, 대화형 명령줄 유틸리티는 이 클래스를 사용하여 마지막 명령 실행을 취소하거나 네트워킹 라이브러리가 이전 요청을 무효화하는 다른 요청을 보내 요청을 취소할 수 있습니다, 또는 네트워킹 라이브러리가 이전 요청을 무효화하는 다른 요청을 보내 요청을 취소할 수 있습니다.
📍 Topics
🔗 Registering Undo Operations
func registerUndo<TargetType>(withTarget: TargetType, handler: (TargetType) -> Void)
func registerUndo(withTarget: Any, selector: Selector, object: Any?)
func prepare(withInvocationTarget: Any) -> Any
🔗 Checking Undo Ability
var canUndo: Bool
var canRedo: Bool
func undo()
func undoNestedGroup()
func redo()
📍 Declaration
func registerUndo<TargetType>(
withTarget target: TargetType,
handler: @escaping (TargetType) -> Void
) where TargetType : AnyObject
📍 Parameters
🔗 target
- 실행 취소 작업의 대상입니다.
- 실행 취소 관리자는 유지 주기를 방지하기 위해 대상에 대한
소유되지 않은 참조를 유지합니다.
🔗 handler
- 작업이 취소될 때 실행할 클로저입니다.
- 클로저는 실행 취소 작업의 대상인 단일 인수를 사용합니다.
📍 Discussion
- registerUndo(withTarget:handler:)를 사용하여 실행 취소 스택에서 실행 취소 작업으로 클로저를 등록합니다.
- 등록된 클로저는 실행 취소가 호출되고 실행 취소 작업이 발생할 때 실행됩니다.
- 대상은 실행 취소 관리자가 해당 상태를 실행 취소하거나 다시 실행할 수 있도록
참조 유형
이어야 합니다.
var manager = UndoManager()
var bouquetSelection: NSMutableArray = ["lilac", "lavender"]
func pull(flower: String) {
bouquetSelection.remove(flower)
manager.registerUndo(withTarget: bouquetSelection) { $0.add(flower) }
}
pull(flower: "lilac")
manager.undo()
- 대상과의 유지 주기를 방지하려면 동일한 대상을 참조하는 외부 범위의 변수가 아닌 폐쇄 매개변수에 대해 작업하십시오.
- 예를 들어 위의 코드 목록에서 클로저는 꽃다발 선택에서 직접 작동하지 않고 $0 매개변수에서 작동합니다.
📍 사용해보기
import Foundation
class UndoManagerPractices {
private let undoManager: UndoManager
private var model: [String]
init() {
undoManager = UndoManager()
model = [String]()
}
func append(text: String) {
model.append(text)
undoManager.registerUndo(withTarget: self) {
$0.remove(text: text)
print("---삭제 실행 취소---")
}
}
func remove(text: String) {
model.removeAll {
$0 == text
}
undoManager.registerUndo(withTarget: self) {
$0.append(text: text)
print("---추가 실행 취소---")
}
}
func undo() {
undoManager.undo()
}
func redo() {
undoManager.redo()
}
func printCanUndo() {
if undoManager.canUndo {
print("실행 취소할 작업이 있습니다.")
return
}
print("실행 취소할 작업이 없습니다.")
}
func printCanRedo() {
if undoManager.canRedo {
print("다시 실행할 작업이 있습니다.")
return
}
print("다시 실행할 작업이 없습니다.")
}
func printModel() {
print(model)
}
}
let undoManagerPractices = UndoManagerPractices()
undoManagerPractices.append(text: "----데이터 추가----")
undoManagerPractices.printCanUndo()
undoManagerPractices.printCanRedo()
undoManagerPractices.remove(text: "----데이터 추가----")
undoManagerPractices.undo()
undoManagerPractices.printCanUndo()
undoManagerPractices.printCanRedo()
undoManagerPractices.redo()
undoManagerPractices.printCanUndo()
undoManagerPractices.printCanRedo()
undoManagerPractices.printModel()