在前面例子中,我們介紹了Storyboards 是 Xcode 中設計用戶界面的友好功能。
?
首先,回顧一下我們已經完成的工作。
?
- 將一個正常的視圖控制器嵌入到導航控制器中
- 創建了一個表視圖,并填充了菜單列表
- 使用聯線從一個視圖控制器切換到另一個視圖控制器
?
我們目前還沒有實現詳細視圖,該視圖目前顯示 一個靜態的標簽。我們將繼續完成這個項目。完善這個應用程序。
?
1.賦值視圖控制器類
?
在前面,我們簡單創建了一個視圖控制器,在Storyboard編輯器中,作為一個菜譜的詳細視圖,視圖控制器默認賦值為UIViewController類
?
回到我們的問題,視圖中標簽應該隨著選擇的菜單發生變化,顯然,在UIViewController中需要一個變量存放菜單的名稱。
?
事實上,UIViewController類僅僅提供了基本的視圖管理模型,相當于一個空白的視圖,沒有變量用于存儲菜單名稱。因此,不能直接使用UIViewController類,我們擴展這一類,并創建自己的類(也就是UIViewController的子類)。
?
在項目導航欄中,右擊RecipeBook 文件夾,選擇 New File .....
?
選擇Cocoa Touch 欄目下的Object-C Class 作為模板。
?
將類命名為 RecipeDetailViewController,選擇子類為UIViewController。注意不要選擇With XIB for user interface選項,因為我們將使用Storyboards 設計用戶界面,我們不必創建獨立的interface builder 文件。點擊next。保存文件。
?
接著,我們賦值RecipeDetailViewController 類給視圖控制器。返回Storyboards 編輯器,選擇詳細視圖控制器。在Identity Inspector 窗口,更改類為 RecipeDetailViewController.
?
2.添加變量到定制的類中
?
前面通過繼承UIViewController類,創建了定制的視圖控制器類。然而,這個類和父類沒有任何不同,除非我們添加自己的變量和方法。還有一些工作我們需要實現的:
?
- 賦值一個變量(recipeName)用于數據傳遞 - 當用戶選擇Recipe 視圖中的一個菜單時,必須傳遞菜單名稱到詳細視圖
?
- 賦值變量(recipeLabel) 給文本標簽 - 當前標簽是靜態的,但應該在菜單名稱變化時,更新文本標簽。
?
OK,現在添加2個變量(recipeLabel 和 recipeName)。
?
選擇RecipeDetailViewController.h 文件,為接口添加2個屬性:
?
#import <UIKit/UIKit.h>
?
@interface RecipeDetailViewController : UIViewController
?
@property ( nonatomic , strong ) IBOutlet UILabel *recipeLabel;
?
@property ( nonatomic , strong ) NSString *recipeName;
?
@end
?
@implementation RecipeDetailViewController
?
@synthesize recipeLabel;
?
@synthesize recipeName;
?
?
3.建立變量和UI 元素之間的連接
?
接下來,我們需要連接 recipeLabel 變量到可視化的Label 標簽。在Stroyboards 編輯器,按住Control鍵,并點擊Recipe Detail View Controller 圖標,拖拉到Label對象上。釋放按鈕,彈出變量列表供你選擇,選擇recipeLabel變量。
?
現在,已經連接了變量和Label UI 元素,變量的任何變化將可視化地顯示出來。但是,仍然有一項沒有處理,我們還需要標簽顯示菜單的名稱。因此,在viewDidLoad 方法中,我們添加如下代碼,并設置標簽文本和菜單文本名稱一致。
?
- ( void )viewDidLoad
{
? ? [ super viewDidLoad ];
// Set the Label text with the selected recipe
? ? recipeLabel . text = recipeName ;
}
?
嘗試編譯并運行你的App,哦,在選擇任意菜單項后,詳細視圖完全顯示空白。
?
這是期望的效果,因為 我們還沒有編寫任何代碼傳遞菜單名稱,recipeName 變量是空白的導致文本標簽也是空白的。
?
?
3.使用聯線(Segue)傳遞數據
?
聯線對象用來準備視圖控制器之間的切換,當聯線觸發時,在可視化的視圖切換發生之前,storyboard運行時調用當前視圖控制器的 prepareForSegue:sender: 方法。通過實現該方法,我們可傳遞任何需要的數據給即將顯示的視圖控制器。
?
然而,最好的辦法是給Storyboards 中每一個聯線一個唯一個標識符(identifier),標示符是一個字符串,應用程序使用該字符串來區別不同的聯線。
?
隨著App 越來越復雜,在視圖控制器中,將有更多的聯線
?
選擇聯線,在Identity Inspector 窗口,設置identifier 屬性值。這里,我們將該聯線命名為 showRecipeDetail.
?
接著,我們將在RecipeBookViewController 視圖控制器中實現prepareForSegue:sender: 方法, 是聯線的源視圖控制器。
?
選擇RecipeBookViewController.m 文件,添加如下代碼:
?
- ( void )prepareForSegue:( UIStoryboardSegue *)segue sender:( id )sender
{
? ? if ([segue. identifier isEqualToString : @"showRecipeDetail" ]) {
? ? ? ? NSIndexPath *indexPath = [ self . tableView indexPathForSelectedRow ];
? ? ? ? RecipeDetailViewController *destViewController = segue. destinationViewController ;
?
? ? ? ? destViewController. recipeName = [ recipes objectAtIndex :indexPath. row ];
?
? ? }
}
?
在視圖切換開始的時候,調用prepareForSegue 方法。
?
第一行用來驗證segue 的標識符。在本例中,標識符為showRecipeDetail。
?
第二行調用tableView:indexPathForSelectedRow 獲取選擇的表行。一旦獲取選擇的行,
我們將傳遞給RecipeDetailViewController視圖控制器。一個Segue對象包含了需要在轉換結束后在視圖控制器中顯示的內容。
?
你可以使用segue.destinationViewController 獲得目的視圖控制器。
?
剩下的代碼就是傳遞菜單名稱給目的控制器
?
你現在還無法運行App,當編譯時,會顯示如下錯誤,總結為2類:
?
- tabeView 屬性在 RecipeBookViewController 中沒有找到
?
- RecipeDetailViewController 是什么? Xcode 不認識它。
?
對于第二個錯誤,我們通過引入RecipeDetailViewController 的頭文件。
?
第一個錯誤,我們首先要在RecipeBookViewController.h 文件中,在@end之前添加如下代碼:
?
@property ( nonatomic , strong ) IBOutlet UITableView * tableView;
@synthesize tableView;
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
