天天看點

《iOS創意程式設計家》——第6.5節Undo與Redo機制

本節書摘來自異步社群《ios創意程式設計家》一書中的第6章,第6.5節undo與redo機制,作者 林柏全,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

6.5 undo與redo機制

ios創意程式設計家

還記得第5章在提到uitextview的時候是怎樣實作undo機制的嗎?其實,iphone os3.0以後就内建了undo-redo的機制。在預設的情況下,每一個應用程式的window對象都提供一個nsundomanager對象,用以管理undo與redo的操作,而視窗内的每一個控件也都有其各自的nsundomanager對象。

這個undo-redo機制是怎麼運作的呢?首先,它會有兩組堆棧(stack),分别用來存放undo與redo的操作,而每一個操作都會以nsinvocation這個類來封裝。很明顯地,在這個類裡面必須記錄這個操作所使用的選擇器(selector)、這個選擇器的資訊接收者以及所有的參數。

這裡用一個例子來說明這一對堆棧的運作情況。假設有一個文本框textview,使用者将原先的文字“abc”修改為“def”,則這個修改的操作将會被以“反向”操作方式推入堆棧,也就是說将使用者輸入的“def”的文字還原為“abc”的操作,如圖6.20所示。

《iOS創意程式設計家》——第6.5節Undo與Redo機制

當我們按下“undo”後,textview的文字會改回“abc”,而這時候nsinvocation a會推出undo堆棧,此時,redo堆棧則是一個與nsinvocation a相反的操作nsinvocation b。

從上面的說明來看,當執行了一項操作時,我們必須要提供給nsundomanager一個反向的操作。例如:當我們新增了一筆資料時,其反向操作就是将這筆資料删除。看起來,我們的程式代碼似乎得多寫不少東西。好在大部分的圖形化控件都有其各自的nsundomanager,是以要在原有的程式上加上undo與redo的功能其實是很簡單的。接下來,我們可以把在第5章寫的uitextviewdemo這個例子稍微改寫一下,如下所示:

上面程式中批注的部分就是我們尚未介紹nsundomanager之前的做法,但是有了nsundomanager之後,隻需要簡簡單單的一行就可以實作undo的功能了。當然,也可以再加上redo的功能,隻要調用[[content undomanager] redo]就可以了。

雖然部分圖形化控件都提供這種功能,但是,我們是否也可以将undo-redo機制應用在其他非圖形化控件上呢?其實也是可以的,不過我們需要自己産生一個nsundomanager,并建立相對應的undo與redo機制。例如:

應用範例:破裂的手機

現在我們要應用undo-redo機制以及搖晃事件的檢測來制作一個有趣的應用程式。這個應用程式一開始會讓界面呈現破碎的樣子,當然這并非是真的,而是我們制作出來的效果。但是當其他人看到這個界面的時候,肯定會很吃驚。這時候,隻要搖晃一下手機就會恢複原狀,再搖晃一次界面就會變成破碎的模樣。

學習重點:

undo-redo機制的使用

搖晃事件的應用

動畫的使用

建立一個single view的項目,并命名為“brokeniphone”。

在建立項目過程中,請記得勾選“use storyboard”以及“use automatic reference counting”選項。

在項目中加入兩張手機的界面。

在設計界面中加入image view控件,如圖6.21所示。

打開“mainstorybard.storyboard”并從控件庫中加入一個image view控件到界面中。這時候,請指定該控件的圖形為破碎後的手機界面。

《iOS創意程式設計家》——第6.5節Undo與Redo機制

選中界面中的手機背景,然後打開編輯器的輔助模式,按住“control”鍵後拉到viewcontroller.h以建立outlet。完成後,我們先在viewcontroller.h中定義一個nsundomanager的變量以及restorescreen和breakscreen這兩個方法,代碼如下:

打開viewcontroller.m,并編輯如下:

處理晃動事件的第一步就是讓目前的viewcontroller可以成為first responder。

由于我們要讓undomanager在undo與redo間不斷切換,是以,我們可以通過canundo這個方法來判斷在undo堆棧裡面是否有invocation。

這樣就完成了晃動事件的處理。

現在開始初始化undomanager。由于剛開始的界面是破碎的模樣,是以,我們在undo的堆棧裡面要建立一個恢複原狀的invocation。

這兩個方法的操作剛好相反,包括加載的圖形以及堆棧内的invocation。我們在每一個操作内都要去建立相反的操作,這樣在堆棧内才有相反的操作可以還原回去。現在,您可以拿着這個應用程式去吓唬您的朋友,相信他們應該會吓一跳吧。不過這樣的應用程式并不适合上架,被apple拒絕的幾率也十分高,讀者們可以好好思考一下其中的原因。

繼續閱讀