iOS: 爲畫板App增加 Undo/Redo(撤銷/重做)操作

這個隨筆的內容以上一個隨筆爲基礎,(在iOS中實現一個簡單的畫板),上一個隨筆實現了一個簡單的畫板:

 
今天我們要爲這個畫板增加Undo/Redo操作,當畫錯了一筆,可以撤銷它,或者撤銷之後後悔了,還可以還原。而且我們要通過晃動手機來觸發Undo/Redo的選擇。
 
這個demo使用NSUndoManager實現Undo/Redo操作,NSUndoManager 的實現原理是它作爲一個記錄器,每次數據變化,我們要用這個記錄器記錄一個相反的操作,當需要undo的時候,它通過執行這個相反的操作就可以實現了。對於這個畫板demo,我們通過把array中的Line首尾連接起來實現的,所以要想還原到上次的狀態,我們通過從array中remove最後添加的那條線就可以實現了。
 
NSUndoManager需要兩個步驟:
第一步,註冊NSUndoManger操作,既上邊提到的註冊一個相反的操作。(先只實現undo操作)
首先添加一個相反的操作,即一個從array中remove Line的方法,方法名就叫removeLine:
 
然後修改addLine方法,註冊剛剛添加的removeLine方法:
 
但是這裏有一個問題:因爲當手指在屏幕移動的時候,touchMove方法會被持續多次觸發,所以畫一筆,是由多個Line組成的。所以addLine會調用多次,如果我們直接undo,只是remove掉了一條Line,但是畫一筆是由多個Line組成,這樣只能移掉一筆中的一部分,即結尾的那部分。
 
那要怎麼辦呢?如何一次移除多個Line,即畫一筆所包含的一組Line。
NSUndoManager有一個分組的概念,就是爲了解決這類問題的。
正常情況下,畫一筆肯定會觸發3個方法,依次是touchBegan, touchMove 和 touchEnd,所以我們可以通過touchBegan和touchEnd就能分辨出畫一筆的開始和結束。既:
 
這樣我們再執行撤銷的時候就是一次remove一組的Line了。
 
第二步,執行Undo
在UI添加一個按鈕,作爲Undo按鈕,按鈕的點擊事件中簡單地調用undo方法就可以了。既:
 
Undo操作這樣就算是完成了。
Redo操作和Undo操作道理一樣,我們只需要修改下removeLine方法,當remove一條Line的時候,也註冊一個相反的操作,即註冊addLine方法,修改後的removeLine方法:
 
晃動觸發Undo/Redo操作
其實我們根本不需要在UI添加Undo/Redo按鈕,直接晃動手機就會自動彈出Undo/Redo選項,而且晃動的功能是自動打開的。
如果需要關閉它,需要設置:
在這個demo中,請不要將此屬性設置爲NO。
 
最後看下效果:(在模擬器中無法晃動,使用快捷鍵進行了模擬)
 

 

相關源代碼:github 

作者:backslash112 
出處:http://sirkevin.cnblogs.com/ 
GitHub:https://github.com/backslash112/ 
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。 
分類: iOS
發佈了40 篇原創文章 · 獲贊 11 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章