這裡我們用一個demo來說明ios是如何在視圖控制器之間傳遞重要的參數的。本文先從手寫UI來讨論,在下一篇文章中讨論在storyboard中傳遞資料。
首先建立一個空工程,并添加一個根視圖控制器類,如下圖所示:

#
在函數didFinishLunchingWithOption中添加幾行代碼,完成後如下:
完成以後運作,iOS模拟器顯示結果如下:
由圖中可以看出,我們自定義的myRootViewController已經成功在啟動時加載,顯示出了一個淺灰色的界面。
随後如法炮制建立另一個viewController命名為FirstSubViewController,同時在RootViewController的viewDidLoad函數中添加如下代碼:
之後還需定義一個函數,名為displayNextViewController,函數體暫時設為空。此時運作程式,界面中央将顯示一個按鈕“顯示下一個視圖”,但是單擊該按鈕沒有任何反應。這是因為響應函數displayNextViewController還沒有實作。現在在該函數中添加代碼:
完成後運作程式發現,按鈕已經有反應了,按下後回出現一個新的白色背景的新界面,這就是我們在這裡定義的firstSubVC;
下一步實作界面的傳回操作。在FirstSubViewController的viewDidLoad函數中建立一個回退按鈕,并實作其響應函數。代碼如下:
到此為止,我們已經通過presentViewController和dismissViewController實作了視圖的切換,下面來考慮兩個視圖控制器之間的資料交流的問題。
在此之前,分别在RootViewController和FirstSubViewController中添加一個标簽和文本框,作為資料的顯示和輸入部分。我們的目的是在FirstSubViewController中輸入一個數字,然後再RootViewController顯示出來。
在這兩個類中分别用property來實作文本框和标簽欄:
在這兩個視圖控制器的viewDidLoad中分别添加如下代碼:
在視圖控制器之間進行資料傳遞可以通過多種方法,下面将逐個實驗:
1、使用代理delegate的方法:
基本原理:FirstSubViewControllers試圖改變RootViewController的資料,但是除了操作自己内部的資料的能力之外,不能改變其他類的資料。想要将這些資料傳遞出去,需要設定代理方法,擷取FirstSubViewControllers中資料的類來遵循該方法,通過實作該代理協定中的方法來擷取FirstSubViewControllers中的資料。
具體步驟:
首先在FirstSubViewController.h中定義協定:
然後添加一個符合該協定的代理屬性:
在RootViewControlller.h中,聲明該類符合FirstSubViewControllerDelegate協定:
在建立FirstSubViewController的執行個體後,将其delegate屬性定義為self,同時實作協定中的方法,兩個函數如下:
最後在FirstSubViewController.m的goBackToPreviousViewController中添加一句向delegate屬性發送擷取資料的消息:
這樣,大功告成了,在FirstSubViewController中的輸入框中輸入的内容,在按傳回按鈕後回顯示在第一個界面的标簽上。
2、使用通知Notification的方法
關于通知的知識在未來将會詳述,在這裡隻是簡要介紹一種使用通知這一機制的方法。
在使用通知之前,必須在預設通知中心裡添加一個所謂“觀察者”和通知,這個通知是命名的,同時還指定了回調的方法。當該通知中心收到了某個對象發送了相應的通知時,将會調用指定的方法執行某項操作。通知的發送者同時還可以發送相應的消息作為通知的參數。
注冊通知中心可以在RootViewController.m中的viewDidLoad函數的末尾添加如下函數:
此外還要實作觀察者的回調函數:
自此通知的接收端已經完成。
通知的發送端,隻需在“傳回上級界面”的相應函數中按照事先定義的名稱發送通知和參數即可:
此時運作,将會發現和代理模式起到了相同的作用。
除了代理和通知之外,還有其他如KVO等方法,未來還會詳細探讨。