對(duì)用戶界面進(jìn)行布局后,接下來就需要讓用戶與界面進(jìn)行交互。這時(shí)就要使用控制器了。控制器能響應(yīng)用戶操作并使用內(nèi)容填充視圖,從而支持您的視圖??刂破鲗?duì)象是一個(gè)管道,通過它,視圖能了解數(shù)據(jù)模型的修改,反之亦然。應(yīng)用程序的控制器會(huì)通知視圖有關(guān)模型數(shù)據(jù)中的修改,之后控制器會(huì)將用戶發(fā)起的修改(例如,在文本欄中輸入的文本)傳達(dá)到模型對(duì)象。不論模型對(duì)象是響應(yīng)用戶操作,還是定義瀏覽,控制器都會(huì)實(shí)現(xiàn)應(yīng)用程序的行為。
構(gòu)建了基本的視圖層次后,下一步就需要控制可視元素并響應(yīng)用戶輸入。在 iOS 應(yīng)用程序中,您可以使用視圖控制器 (UIViewController) 來管理內(nèi)容視圖及其分視圖層次。
視圖控制器并不是視圖層次的一部分,也不是界面中的元素。相反,它管理著層次中的視圖對(duì)象,并為它們提供行為。在串聯(lián)圖中構(gòu)建的每個(gè)內(nèi)容視圖層次,都需要一個(gè)對(duì)應(yīng)的視圖控制器來管理界面元素,并執(zhí)行任務(wù)來響應(yīng)用戶的交互操作。通常,這意味著您需要為每個(gè)內(nèi)容視圖層次編寫一個(gè)自定 UIViewController 子類。如果應(yīng)用程序有多個(gè)內(nèi)容視圖,那么就需要為每個(gè)內(nèi)容視圖使用不同的自定視圖控制器類。
視圖控制器扮演著多種角色。它們負(fù)責(zé)協(xié)調(diào)應(yīng)用程序的數(shù)據(jù)模型與顯示該數(shù)據(jù)的視圖之間的信息傳輸,管理應(yīng)用程序的內(nèi)容視圖的生命周期,并處理設(shè)備旋轉(zhuǎn)時(shí)方向的更改。但其最主要的作用可能是響應(yīng)用戶輸入。
您還可以使用視圖控制器來轉(zhuǎn)換各種類型的內(nèi)容。由于 iOS 應(yīng)用程序顯示內(nèi)容的空間很有限,因此視圖控制器提供了所需要的基礎(chǔ)結(jié)構(gòu),可讓您移除一個(gè)視圖控制器的視圖,替換為另一個(gè)視圖控制器中的視圖。
通過讓視圖控制器文件與串聯(lián)圖中的視圖進(jìn)行通信,可以定義應(yīng)用程序中的交互方式。方法是通過 Action 與 Outlet 來定義串聯(lián)圖與源代碼文件之間的連接。
操作 是一段代碼,它與應(yīng)用程序中可能會(huì)發(fā)生的某類事件相鏈接。該事件發(fā)生后,代碼就會(huì)執(zhí)行。您可以定義操作來完成任何事情:從操控?cái)?shù)據(jù)到更新用戶界面。操作可驅(qū)動(dòng)應(yīng)用程序的流程來響應(yīng)用戶事件或者系統(tǒng)事件。
可采用如下方法來定義:使用 IBAction 返回類型和 sender 參數(shù)來創(chuàng)建并實(shí)現(xiàn)方法。
- (IBAction)restoreDefaults:(id)sender;
sender 參數(shù)指向負(fù)責(zé)觸發(fā)操作的對(duì)象。IBAction 返回類型是個(gè)特殊的關(guān)鍵詞。它與 void 關(guān)鍵詞類似,但它表示該方法是一種操作,您可以在 Interface Builder 的串聯(lián)圖中連接到這種操作(這就是這個(gè)關(guān)鍵詞有 IB 前綴的原因)。在串聯(lián)圖中,您會(huì)了解如何將 IBAction 操作鏈接到串聯(lián)圖中元素的更多知識(shí)。
Outlet 可讓您從源代碼文件引用界面中的對(duì)象(添加到串聯(lián)圖的對(duì)象)。您可以按住 Control 鍵,并將串聯(lián)圖中的特定對(duì)象拖移至視圖控制器文件來創(chuàng)建 Outlet。這就為視圖控制器文件中的對(duì)象創(chuàng)建了屬性,通過該屬性,您可以在運(yùn)行時(shí)通過代碼來訪問并操控該對(duì)象。例如,在第二個(gè)教程中,您將為 ToDoList 應(yīng)用程序中的文本欄創(chuàng)建 Outlet,這樣就可以用代碼的形式訪問文本欄的內(nèi)容。
Outlet 被定義為 IBOutlet 屬性。
@property (weak, nonatomic) IBOutlet UITextField *textField;
IBOutlet 關(guān)鍵詞告訴 Xcode,您可以從 Interface Builder 連接到該屬性。在“教程:串聯(lián)圖”中,您會(huì)了解有關(guān)如何從串聯(lián)圖將 Outlet 連接到源代碼的更多知識(shí)。
控制是用戶界面對(duì)象(例如按鈕、滑塊或者開關(guān)),用戶可以操控它們來與內(nèi)容進(jìn)行交互、提供輸入、在應(yīng)用程序內(nèi)導(dǎo)航,以及執(zhí)行所定義的其他操作。代碼可通過控制來接收用戶界面的消息。
用戶與控制進(jìn)行交互,會(huì)創(chuàng)建控制事件??刂剖录硎居脩艨稍诳刂粕鲜褂玫母鞣N手勢(shì),例如將手指抬離控制、手指拖移到控制上,以及在文本欄中按下。
常見的事件類型有三種:
定義交互時(shí),您應(yīng)該了解與應(yīng)用程序中每個(gè)控制相關(guān)聯(lián)的操作,然后明確地向用戶展示應(yīng)用程序中控制的作用。
如果應(yīng)用程序有多個(gè)內(nèi)容視圖層次,就需要能夠在它們之間進(jìn)行切換。為此,可以使用專門的視圖控制器:導(dǎo)航控制器 (UINavigationController)。導(dǎo)航控制器管理在一系列視圖控制器中向后和向前切換的操作,例如用戶在 iOS 版“郵件”應(yīng)用程序的電子郵件帳戶、收件箱郵件和單封電子郵件之間導(dǎo)航。
我們將由特定導(dǎo)航控制器所管理的一組視圖控制器稱為其導(dǎo)航棧。導(dǎo)航棧是一組后進(jìn)先出的自定視圖控制器對(duì)象。添加到堆棧的第一個(gè)項(xiàng)目將變成根視圖控制器,永不會(huì)從堆棧中彈出。而其他視圖控制器可被壓入或彈出導(dǎo)航棧。
雖然導(dǎo)航控制器的最主要作用是管理內(nèi)容視圖控制器的顯示方式,但它還負(fù)責(zé)顯示自己的自定視圖。具體來說,它會(huì)顯示導(dǎo)航欄(位于屏幕頂部的視圖,提供有關(guān)用戶在導(dǎo)航層次中位置的上下文)。導(dǎo)航欄包含一個(gè)返回按鈕和其他可以自定的按鈕。添加到導(dǎo)航棧的每個(gè)視圖控制器都會(huì)顯示這個(gè)導(dǎo)航欄。您需要配置導(dǎo)航欄。
一般而言,您不必執(zhí)行任何操作來將視圖控制器彈出導(dǎo)航棧;導(dǎo)航控制器提供的返回按鈕會(huì)實(shí)現(xiàn)該操作。但您需要手動(dòng)將視圖控制器壓入堆棧中。可使用串聯(lián)圖來操作。
到目前為止,您已經(jīng)學(xué)習(xí)了使用串聯(lián)圖來創(chuàng)建包含單個(gè)屏幕內(nèi)容的應(yīng)用程序。接下來,將要了解如何使用它們來定義應(yīng)用程序中多個(gè)場景之間的流程。
在第一個(gè)教程中,所使用的串聯(lián)圖只有一個(gè)場景。而在大多數(shù)應(yīng)用程序中,串聯(lián)圖是由一系列的場景組成,每個(gè)場景表示一個(gè)視圖控制器及其視圖層次。場景則由過渡連接。過渡表示兩個(gè)視圖控制器之間的切換:源視圖控制器和目的視圖控制器。
您可以創(chuàng)建以下幾種類型的過渡:
除了過渡之外,還可以通過關(guān)系來連接場景。例如,導(dǎo)航控制器與其根視圖控制器之間就存在關(guān)系。就此而言,這種關(guān)系表示導(dǎo)航控制器包含根視圖控制器。
使用串聯(lián)圖規(guī)劃應(yīng)用程序的用戶界面時(shí),要確定將其中一個(gè)視圖控制器標(biāo)記為初始視圖控制器,這一點(diǎn)尤為重要。運(yùn)行時(shí),該視圖控制器的內(nèi)容視圖會(huì)在應(yīng)用程序首次啟動(dòng)時(shí)顯示,且在需要時(shí),您可以從該視圖控制器切換到其他視圖控制器的內(nèi)容視圖。
現(xiàn)在您已經(jīng)了解了在串聯(lián)圖中處理視圖和視圖控制器的基礎(chǔ)知識(shí)。在下一個(gè)教程中,我們就要將這些知識(shí)運(yùn)用到 ToDoList 應(yīng)用程序的開發(fā)中。
更多建議: