上文中記錄了在手寫代碼實現UI的情況下,介面切換時不同視圖控制器之間資料傳遞的機制。顯示和消除介面使用的函數時presentViewController和dismissViewController函數,資料傳遞則可以採用代理、通知等機制。本文記錄的是使用storyboard實現介面的情況下,採用segue相關的方法實現與上文中相同的功能。
首先要做的是建立一個單視圖工程,建立完成後會產生一組(一個標頭檔和一個源檔案稱為一組)AppDelegate類,一組ViewController類,一個storyboard以及其他一些輔助檔案。然後需要建立一個視圖控制器類,使用快速鍵command+N,選擇Objective-C類,建立一組名為FirstSubViewController的視圖控制器繼承自UIViewController。
下面在storyboard中添加各種控制項。按照之前的設計,將一個Label和一個Button加入到第一個sence中。然後,在storyboard中拖入一個新的視圖控制器,在其中加入一個TextField和一個Button。同時別忘了給控制項添加IBOutlet和IBAction,以及將第二個介面的ViewController類改為我們之前建立好的FirstSubViewController類。
在不同的介面之間建立segue非常簡單,只需要在觸發控制項(比如Button)上按住Ctrl並拖動至新的介面,並在快顯功能表中選擇Modal選項。在Attribute菜單中為segue添加一個ID,然後用類似的方法將第二個ViewController的按鈕segue到第一個介面上。
然後一個在兩個介面之間的segue就已經建立完成,如所示。
此時運行一下程式將會發現,從第一個介面中點擊“顯示下一介面按鈕”,將會跳轉到第二個介面中;點擊“返回上一介面”,將會跳回最初的介面。
然後實現讓第一個介面中的Label擷取第二個介面中TextField中的內容,實現方法很簡單,即在第二個介面的視圖控制器中實現prepareForSegue函數即可。
在ViewController.h中添加一個property,用於接收傳過來的字元:
@property (nonatomic,copy) NSString *stringToReceive;
需要注意的是,不要試圖將UILabel類型的IBOutlet聲明為公開屬性用於接收字串,因為在下面的prepareForSegue的方法中,不能直接擷取到有效Label執行個體。
然後再viewDidLoad函數中判斷該屬性是否為空白,不為空白則賦給標籤:
- (void)viewDidLoad{ [super viewDidLoad];// Do any additional setup after loading the view, typically from a nib. if (_stringToReceive != Nil) { _showText.text = _stringToReceive; }}
在firstSubViewController中實現函數:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if ([segue.identifier isEqualToString:@"goBackToPreviousViewController"]) { if ([segue.destinationViewController isKindOfClass:[ViewController class]]) { ViewController *vc = (ViewController *)segue.destinationViewController; vc.stringToReceive = _inputText.text; } }}這裡面“goBackToPreviousViewController”是自己定義的segue ID。
自此,整個工程就已經完成了,運行測試一下發現一切正常。
本文和上文的兩個demo已經上傳到了資源頁,需要的話可以下載作為參考。