這是我們演示故事板系列的第二篇文章。在前一個教程中,我們介紹了故事板,那是一個在Xcode中方便設計友好用戶界面的功能。如果你跟着教程走,從開始到現在,你應該已經建立了一個簡單的菜單應用程序的導航界面。但是上一篇我們有一件事沒討論,那就是如何在通過聯線(segue)連接的視圖控制器中傳值呢?
首先,讓我們快速瀏覽一下我們已經完成了什么。在此之前,我們學會了使用故事板建立一個下面幾件事情:
>插入一個視圖控制器到導航控制器
>創建一個表視圖並放入一些菜單數據
>使用segue(聯線)從一個視圖控制器到令一個視圖控制器的切換
然后,下面是最后成品了。當應用程序啟動時,它會顯示一個食譜列表。點擊其中的任何一個單元格會把你帶到另外一個視圖,也就是詳細介紹視圖,雖然我們什么也沒加。

菜單應用程序的詳細信息控制器
我們沒有實現詳細視圖,現在顯示了一個靜態的標簽。因此,我們將繼續努力,在這個項目上繼續完善應用程序。
分配視圖控制器類
前一個教程中,我們簡單地創建一個視圖控制器來作為菜單詳細信息視圖。默認情況下,視圖控制器指定為UIViewController類。
讓我們重新審視我們的問題。在視圖中的標簽應改變為相對於所選菜單。很明顯,必須有用於存儲菜單名稱一個變量的UIViewController。
事實是UIViewController類提供了基本的視圖管理模式。它對應於一個空白視圖。沒有任何變量分配給存儲的食譜名。因此,而不是直接使用UIViewController,我們擴展它創建自己的類(稱為UIViewController子類)。
在項目瀏覽器中,用鼠標右鍵單擊“RecipeBook”文件夾並選擇“New File ...”。

在Xcode項目中創建新文件
選擇“Objective-C類的類模板”下的Cocoa Touch的。

選擇目標C類
將該類命名為為“RecipeDetailViewController”和它的一個子類“UIViewController”。請確保取消選中“with XIB for user interface(XIB用戶界面)”的選項。我們正在使用演示板設計用戶界面,我們不需要創建一個單獨的界面生成器文件。單擊“下步”,在你的項目文件夾中保存文件。

創建一個RecipeDetailViewController的類(子類的UIViewController)
下一步,我們必須指定RecipeDetailViewController類的視圖控制器。回到故事板編輯器和選擇詳細視圖控制器。在身份檢查,改變類的為“RecipeDetailViewController”。

更改視圖控制器類
在自定義類里添加變量
我們剛剛創建從UIViewController類繼承的自定義視圖控制器類。但是,它和父類不同,因為我們可以添加我們自己的變量和方法。有一些事情,我們必須改變:
>聲明變量(recipeName)來傳遞數據---當用戶從菜單視圖中選中菜單,必須有個方法把值傳遞到詳細視圖中。
>聲明變量(recipeLabel)給文本標簽--標簽是靜態的,必須用菜單名來更新。
好吧,讓我們添加這些的兩個的變量(recipeLabel和recipeName)。選擇“RecipeDetailViewController.h”,並增加了兩個屬性的接口:
1
2 3 4 5 6 |
@interface
RecipeDetailViewController
:
UIViewController
@property (nonatomic, strong ) IBOutlet UILabel *recipeLabel; @property (nonatomic, strong ) NSString *recipeName; @end |
轉到的“RecipeDetailViewController.m”,並添加下面變量。確保你的代碼放在“@ implementation RecipeDetailViewController”下:
1
2 3 4 |
@implementation
RecipeDetailViewController
@synthesize recipeLabel; @synthesize recipeName; |
建立變量與用戶界面的連接
接下來,我們就將"recipeLabel"與可視化標簽連接起來。在故事板編輯器,按命令鍵,然后單擊“菜單詳細信息視圖 - 控制器”圖標,將其拖動到標簽對象。放開兩個按鈕,彈出一個顯示變量的選擇。選擇變量“recipeLabel”。

UI元素和變量之間建立連接
就是這樣。現在你已經連接標簽與變量。視覺上的任何變化將反映在變量上。但是,仍然有一件事情。我們希望有標簽,以示菜單名稱。因此,在viewDidLoad函數中,我們添加以下代碼,設置標簽文本與選中菜單名稱相同。
1
2 3 4 5 6 |
-
(
void
)viewDidLoad
{ [super viewDidLoad ]; // Set the Label text with the selected recipe recipeLabel.text = recipeName; } |
嘗試編譯並運行您的應用程序。哎呀!詳細信息視圖中,選擇任何配方后,是完全空白的。這是預期的行為。因為我們沒有寫任何代碼來傳遞的菜單名稱。因此,“recipeName”變量是空的,空的文本標簽。

Receipe為空的詳細信息控制器的應用程序
使用聯線(segue)來傳遞數據
現在到了教程的核心部分,有關如何使用Segue實現視圖控制器之間的數據傳遞。Segues管理視圖控制器之間的過渡。在此之上,SEGUE對象是用來准備從一個視圖控制器過渡到另一個。當SEGUE被觸發,視覺過渡發生之前,演示圖板運行時調用prepareForSegue:sender:當前視圖控制器的方法(在我們的例子中,這是RecipeBookViewController)。通過實施這一方法,我們可以將任何需要的數據傳遞到要顯示的視圖控制器中
然而,最好的做法是給每條聯線(segue)賦予一個獨特的標識符(unique identifier。這個標識符是一個字符串,應用程序使用它以區分不同的聯線(SEGUE)。您的尤其當應用程序變得更加復雜,很可能你將有一個以上的聯線來連接視圖控制器的時候,就尤為必要。
要指定標識符,選擇聯線(SEGUE),並在標志檢查(identity inspector)將其設置。讓我們命名那根聯線(SEGUE)為 “showRecipeDetail”。

故事板Segue公司標識
接下來,我們將在源代碼中實現prepareForSegue:sender:方法“食譜 - 視圖 - 控制器。選擇“RecipeBookViewController.m”,並添加下面的代碼:
1
2 3 4 5 6 7 |
-
(
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方法會被調用。第一線是用來驗證聯線標識符。在這種情況下,判斷聯線標識符是否為“showRecipeDetail”。第二行代碼調用的tableView:indexPathForSelectedRow的檢索選定的表行。第三行,得到跳轉的目標視圖,這里為RecipeDetailViewController。最后行,得到選定表行的行數,用行數得到選定菜單數據,賦值給目標視圖的變量recipeName。由於先前把recipeName變量的值賦給標簽,故詳細視圖可以顯示菜單名。
但是您不能運行你的應用程序。在復制和粘貼上面的方法到RecipeBookViewController.m,您應該會看到一些錯誤。

prepareForSegue錯誤
如上圖所示,有三個錯誤。但是我們可以歸納為兩種:
>RecipeBookViewController沒有找到tableView
>什么是RecipeDetailViewController?Xcode,不知道它是什么。
讓我們先談第二個錯誤。對應RecipeBookViewController,它不知道有關RecipeDetailViewController的信息。在Objective C中,您可以使用“#impoet”指令來導入其他類的頭文件。導入頭文件“RecipeDetailViewController.h”,RecipeBookViewController可以訪問詳細信息視圖控制器屬性和方法的。在開始的時候添加將下面的代碼來修復錯誤:
1
|
#import “RecipeDetailViewController.h”
|
關於第一個錯誤,你應該知道如何解決它。這是我們前面討論過的標簽UI元素。應該有一個相應的變量tableView連接的UI變量。
因此,在的RecipeBookViewController.h,添加下面的代碼“@end”之前:
1
|
@property
(nonatomic, strong
)
IBOutlet UITableView
*tableView;
|
對於RecipeBookViewController.m,添加的合成指令告訴編譯器生成的tableView變量的存取方法。
1
2 3 4 5 |
@implementation
RecipeBookViewController
{
NSArray *recipes; } @synthesize tableView; // Add this line of code |
最后,回到故事板把變量和UI元素連接起來。在“食譜 - 視圖 - 控制器”,按住Command鍵並單擊視圖控制器圖標,將其拖動到表視圖。松開左鍵選擇“tableView”。

建立連接的tableView變量
現在,所有的錯誤應該得到解決。讓我們嘗試編譯和運行的應用程序。這個時候,你的應用程序應該按預期工作顯示。盡量選擇任何菜單,可看到詳細視圖顯示所選項目的名稱。

菜單應用程序 - 我們的最終交付
接下來會發生什么呢?
建立一個應用程序的導航界面,是不是很容易嗎?隨着故事板的推出,大大減少了你需要的代碼來處理。最重要的是,集中式的故事板流給應用程序接口提供了一個高層次的構建平台。我希望這兩個教程,讓你知道故事板的工作原理,以及你可以利用它來構建自己的應用程序。雖然我們已經創建的應用程序很簡單,舉一個簡單的UI,並闡述基本概念,您可以依據它來建立更復雜的應用程序。
在以后的教程中,我們將探討的靜態表格單元格,並繼續使應用程序甚至更好的選項卡控制器,敬請關注,。