티스토리 뷰

iOS

iOS ) Task Management - Undo - UndoManager

Zedd0202 2018. 11. 2. 13:32
반응형

안녕하세요 :) Zedd입니다.

타이머를 다룰 일이 생겨서...사실 진짜 iOS처음했을 때 zzzzz 타이머를 다뤘었거든요

근데 그때는 진짜 쓰기에 급급하고 막 문서 볼 생각도 안하고 그랬어서..

이번에 제대로 공부해보려고 해요 XD


.....


해가지고 타이머를 제대로 공부하려고 했는데

Task Management를 먼저 볼게요. 



Task Management는 말그대로 Task 관리.

앱의 작업(work)와 사용자 및 시스템과의 상호작용을 관리하는 거에요.


토픽으로는 


Undo

Progress

Operations

Scheduling(여기에 타이머가 있어요!)

Activity Sharing

System Interaction

User Notifications


이렇게 있는 것 같아요.



Undo를 먼접 봅시다.




UndoManager라는 거..있는지...몰랐음..

알아야 할게 너무나도 많다. ^_ㅠ


UndoManager클래스의 정의는 Undo 및 Redo 할 수 있는 작업의 범용(general-purpose) 레코더입니다.

Registering Undo Operations에 정의된 메소드들 중 하나를 호출하여 undo operation을 등록합니다.

변경하는 객체의 이름(또는 해당 객체의 소유자)을 지정하고 상태(state)를 되돌리기 위해 closure, method, invocation을 제공합니다.

undo operation을 등록 한 후, undo manager에서 undo()를 호출하여 마지막 실행 취소 작업(last undo operation) 상태로 되돌릴 수 있습니다. 작업을 취소 할 때, UndoManager는 redo()를 자동으로 호출 할 수 있도록 되돌려 놓은 작업을 저장합니다.

UndoManager는 일반적으로 UI상호작용이 있는 앱에서 사용됩니다. 예를들어 UIKit은 TextView객체에서 undo 및 redo를 구현하므로, responder chain을 따라 객체에서 작업을 쉽게 undo하고 redo할 수 있습니다. 


지금 쭉 Task Management를 훑어봤는데 아악 다 알고싶은

그래서 이 글을 이렇게 쓰는게 맞나 싶은 고민이 드네요.

따로따로 하나씩 쓰고싶은데...

그렇다면 제목에 Undo를 붙혀야겠다.


UndoManager를 어떻게 쓰는지 알아봅시다. 



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")

// bouquetSelection == ["lavender"]

manager.undo()

// bouquetSelection == ["lavender", "lilac"]



자, 애플문서에 있는 예제인데요, 굳이 NSMutableArray로 한것은......remove메소드 때문이 아닐까 싶네요. 

암튼 그게 중요한게 아니라,


pull(flower: "lilac")

// bouquetSelection == ["lavender"]

manager.undo()

// bouquetSelection == ["lavender", "lilac"]



pull로 라일락을 배열에서 제거했으니 배열에는 라벤더만 남았죠?

근데 그걸 undo. 즉 실행취소를 하니까 다시 배열에 라일락이 생긴것을 볼 수 있습니다!


overView에서 말했듯이, undo operation을 등록해야하는데요, 




var manager = UndoManager()

var bouquetSelection: NSMutableArray = ["lilac", "lavender"]

func pull(flower: String) {

    bouquetSelection.remove(flower)

    manager.registerUndo(withTarget: bouquetSelection) { $0.add(flower) }

}



바로 이것이죠. 이 메소드에 대해서 알아봅시다. 


특정 closure를 등록하여 대상(target)이 수신하는 single undo operation을 구현합니다.


자 정의는 이렇게 생겼어요. 파라미터로 타겟과 핸들러가 있습니다.


타겟은 undo operation의 대상이에요.

눈여겨 볼만한 점은..undo manager는 retain cycles을 방지하기 위해서 target을 unowned reference로 유지한다고 합니다.


핸들러는 작업이 취소될 때 실행할 클로져에요.


registerUndo(withTarget:handler:)를 사용하여 undo스택에서 closure를 undo operation으로 등록합니다. 그러면 undo가 호출되고, undo operation이 발생 할 때, 등록한 closure가 실행됩니다. target은 reference type이어야, undo manager가 상태를 undo하거나 redo할 수 있습니다.


오ㅇ옹 UndoManager로 이런것도 가능합니다.







github에 올라와있길래..!! 코드는 https://github.com/adarshvcdev/swiftundomanager 에 있습니다!!!!

신기하죠..!!



undoManager?.canUndo


undoManager?.canRedo


이렇게 지금 undo / redo할 수 있는지도 체크 할 수 있고, 



undoManager?.removeAllActions()


이렇게 undo / redo stack을 모두 제거 할 수 도 있습니다. 


UndoManager라는게 있는지도 몰랐는데..

앞으로 이런게 얼마나 많을까요

다 알때까지 화이팅 XD




반응형