やり直し・繰り返しを制御するUndoManagerを使ったときに悩んだことをちょこっとメモ。 CoreDataやUIWebViewにはくっついてたりするので、自分でゴリゴリソースを書くことはあんましない・・・かも?
基本的な使い方
基本的には何かの処理をしたときに、その処理を打ち消す動作をUndoManagerに登録してあげます。 UndoするときにはUndoManagerが勝手にその打ち消す動作を実行してくれます。 処理の登録法は、例えばobjAのfunctionが打ち消す動作だとすると、
[[undoManager prepareWithInvocationTarget:objA] function];
と言った形になります。 引数がある時も同じです
[[undoManager prepareWithInvocationTarget:objA] functionWithObject:objB];
Redoは自動的に登録される
Redoに関しては何もソースを書く必要はありません。 UndoがきちんとできていればRedoは自動的に登録されます。 なぜかというと、undoする間にさらにそれを打ち消す動作がundoManagerに登録されるからです。 値Aを1→2に変えたとします。それを打ち消す動作は2→1に変える動作です。 この打ち消す動作である2→1の間にも更にそれを打ち消す動作である2→1がundoManagerに登録されます。 これがRedoの登録になります。 なので、undoがきちんとできていればRedoは勝手に登録されるんです。 ちょっとお得ですね!
自動でグループ化される
Widthを変更してHeightも変更するみたいなときは、undoしたときに一緒に元に戻って欲しいですよね? それを行なってくれるのがグループ化です。 WidthとHeightの値の変更を同じグループ内で行えば、undoしたときに一緒に元に戻ってくれます。 しかし、これもあまり意識しないでいいです。 何故ならば、自動でグループ化されるからです。 Widthを変更してHeightも変更するときはたいてい続けて処理を書きますよね?それは同じグループになります。 グループがわかれるのはシステムに処理が戻った時です。(変えたければ設定で変えられます。) 逆に言えばシステムに処理が戻らなければずっと同じグループなので、気を付けないと大変です。
グループ化、redoは何もしなくてもいいとはいえ、知識としては知っておかないと変なソースを書いてしまうので 頭の片隅にでも入れておくのがいいと思います。