07 2月

使用Storyboard构建Navigation Controller和Table View

文 / Simon Ng:iOS程序员,Beginning iOS 9 Programming with Swift一书的作者,AppCoda.com创始人。

原文链接:http://www.appcoda.com/use-storyboards-to-build-navigation-controller-and-table-view/

到现在为止,如果一直跟着我们的教程学习,你应该有了对UITableView基本的了解。并且知道如何利用它构建简单的应用程序了。本周,我们要说说新东西,Storyboards。这是Xcode 4.2和iOS 5 SDK引入的最令人激动的功能特性之一。作为iOS开发人员,它使你的生活更简单,可以轻而易举地设计iOS应用程序的用户接口。

本文将向你展示如何使用Storyboards构建Navigation接口,并将它与UITableView集成起来。我们会尽力保持简单,集中精力解释概念。因此就没有好玩儿的界面和漂亮的图形。以后的文章会解决艺术性的问题。

好,我们开始吧!

什么是Navigation Controller?

我们开始编码前,像以往一样,我们对Navigation Controller和Storyboards做一个简单的介绍。

就像Table View,Navigation Controller是你在iOS应用程序中另一种最常见的UI元素。它提供了逐层向下的层次内容。看一看内置的Photos,YouTube 和Contacts应用,这些应用程序都使用了Navigation Controller来显示分层的内容。通常,大多数应用程序中的Table View和Navigation Controller是一起工作的。但这并不是说一定要两个一起使用。

Photos-App-Navigation-Controller

Storyboards概览

前面说过,Storyboard是Xcode 4.2以来引入的新功能特性。它为iOS开发者提供了创建和设计用户界面提供了全新的方式。对初学者来说,介绍Storyboard之前,创建导航界面和标签界面着实困难。每个界面都存储在单独的nib文件中。在这之上,还要编写代码讲所有的界面连接到一起,描述导航如何工作。

有了Storyboards,所有的界面都存储在一个文件中。这给了你一种应用程序可见的表现方式,向你展示了这些界面是如何连接在一起的。Xcode提供了内置的编辑器来编辑Storyboards的布局。通过简单的点击,你可以定义不同界面之间的转变(也就是所谓的segues)。这并不意味着不需要为用户界面编写代码。但Storyboards显著减少了编码量。下面的示例图片展示了Storyboards在Xcode中的样子。

Storyboards-Explained

Scene和Segues

使用Storyboards时,Scene和Segues是总出现的两条术语。在Storyboard中,scene指一个单独的视图控制器和它的视图。每一个scene都有一个dock,dock主要被用来在视图控制器和它的视图之间做action和outlet关联。

Segue位于两个scene之间,管理两个scene之间的转变(transition)。Push和Modal是转变的两种常见类型。

在Storyboards中创建Navigation Controller

我们现在动手创建Storyboards。在本文中,我们将构建一个使用UITableView和UINavigationController的简单示例应用。使用Table View显示菜谱。当用户选择任何一道菜时,应用程序就跳转到下一个页面显示细节。这不难的。

首先,启动Xcode(确保使用4.2版本以上),使用“Single View application”模版创建一个新的项目。

Choose-Xcode-Template

点击“Next”继续。把下图中Xcode项目中需要填写的内容补齐。确认勾选“Use Storyboards”选项。

RecipeCookbook-Xcode-Project

点击“Next”继续。Xcode会询问把“SimpleTable”存到哪里。选择任一文件夹(例如,桌面)保存你的项目。

你可能注意到了Xcode项目中细微的差别。与之前文章中的内容比较,.xib文件(interface builder)被MainStoryboard.storyboard文件代替了。

Empty-Storyboard-in-Xcode

默认情况下,Xcode创建一个标准的视图控制器。因为我们要使用Navigation Controller控制界面导航,首先要将view controller修改为navigation controller。直接选择“Editor”菜单,选择“Embed in”,然后选择“Navigation Controller”。

Storyboard-Embed-in-Navigation-Controller

Xcode会自动给RecipeBook View Controller嵌入Navigation Controller。界面看起来是这个样子的:

Storyboard-Added-with-Navigation-Controller

继续网下进行前,我们运行一下程序,看看是什么样子的。点击“Run”按钮,你应该能看到一个添加了导航条的空白视图。这表明已经成功地把RecipeBook View Controller嵌入到了Navigation Controller中了。

RecipeBookApp-Empty

为数据添加Table View

接下来,我们会添加Table View,显示菜谱。在对象库中选择“Table View”,拖拽到“Recipe Book View Controller”。

请注意,不能把这些对象拖拽到缩小了的编辑器中,如果无法把table view拖拽到view controller,放大后再试。

Storyboard-Add-Table-View

下一件要做的事情是编写代码表格数据(也就是菜谱)。在项目导航栏,选择“RecipeBookViewController.h”,在“UIViewController”后面添加协议参数。

#import <UIKit/UIKit.h>

@interface RecipeBookViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@end

如果你读过Simple Table有关的文章,应该非常熟悉上面的代码。我就不在解释细节 了。如果理解起来有困难,查阅一下更早的文章

接下来,选择“RecipeBookViewController.m”,为保存表格数据定义实例变量(也就是菜单数组)。

@implementation RecipeBookViewController {

NSArray *recipes;

}

在“viewDidLoad”方法中,添加如下代码初始化“recipes”数组:

– (void)viewDidLoad

{

[super viewDidLoad];

//Initialize table data

recipes = [NSArray arrayWithObjects:@”Egg Benedict”, @”Mushroom Risotto”, @”Full         Breakfast”, @”Hamburger”, @”Ham and Egg Sandwich”, @”Creme Brelee”, @”White Chocolate Donut”, @”Starbucks Coffee”, @”Vegetable Curry”, @”Instant Noodle with Egg”, @”Noodle with BBQ Pork”, @”Japanese Noodle with Pork”, @”Green Tea”, @”Thai Shrimp Cake”, @”Angry Birds Cake”, @”Ham and Cheese Panini”, nil];

}

最后,我们必须实现两个数据源方法,来生成表格数据:

“tableView:numberOfRowsInSection”和“tableView:cellForRowAtIndexPath”方法。调用这两个方法是UITableViewDataSource协议的一部分。配置UITableVIew时,这两个方法是必须要实现的。第一个方法用来通知Table View区域内的行数,而第二个方法被用来填充表数据,因此我们添加如下代码。

作为参考,下面是整个“RecipeBookViewController.m”的源码。

//

//  RecipeBookViewController.m

//  RecipeBook

//

//  Created by Simon Ng on 14/6/12.

//  Copyright (c) 2012 Appcoda. All rights reserved.

//

#import “RecipeBookViewController.h”

@interface RecipeBookViewController ()

@end

@implementation RecipeBookViewController {

NSArray *recipes;

}

– (void)viewDidLoad

{

[super viewDidLoad];

// Initialize table data

recipes = [NSArray arrayWithObjects:@”Egg Benedict”, @”Mushroom Risotto”, @”Full Breakfast”, @”Hamburger”, @”Ham and Egg Sandwich”, @”Creme Brelee”, @”White Chocolate Donut”, @”Starbucks Coffee”, @”Vegetable Curry”, @”Instant Noodle with Egg”, @”Noodle with BBQ Pork”, @”Japanese Noodle with Pork”, @”Green Tea”, @”Thai Shrimp Cake”, @”Angry Birds Cake”, @”Ham and Cheese Panini”, nil];

}

– (void)viewDidUnload

{

[super viewDidUnload];

// Release any retained subviews of the main view.

}

– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);

}

– (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return [recipes count];

}

– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

static NSString *simpleTableIdentifier = @”RecipeCell”;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault     reuseIdentifier:simpleTableIdentifier];

}

cell.textLabel.text = [recipes objectAtIndex:indexPath.row];

return cell;

}

@end

最后,我们建立Table View和刚刚创建的这两个方法之间的连接。返回Storyboard。按住Control键,选择“Table View”,拖拽到View Controller的图标。看起来是这个样子的:

Storyboard-TableView-Datasource

松开按钮,弹出了“dataSource”和“delegate”,选择“dataSource”,在Table View和它的数据源之间建立连接。重复上述步骤,在Table View和代理之间建立连接。

Storyboard-TableView-Connect-Datasource

测试应用程序之前,最后一件事是给导航栏添加标题。直接选择“Recipe Book View Controller”的导航栏,填写“Attributes Inspector”下的“Title”。记住,填写完成后点击ENTER,修改生效。

Storyboard-Add-Navigation-Bar-Title

可以运行代码了。点击Run按钮,测试应用程序。如果代码正确,你应该得到一个显示菜谱列表的应用程序。这个应用和之前我们构建的SimpleTable应用非常相似。这里最主要的区别就是嵌入了Navigation Controller。

Storyboard-Navigation-Bar-Title

Prototype Cell简介

还记得如何自定义表格吗?几周前,我们向你展示了如何使用Interface Builder设计自定义的表格。简要地说,你需要为表格单独创建一个nib文件,并用编程的方法将它加载到表呢。介绍了Storyboard中的Prototype Cell以后,创建自定义表格就更简单了。ProtoType Cell可以让你在Storyboard编辑器中轻松设计好表格的布局。

我们不会在本文深入谈论自定义的细节,而仅仅是在表格中添加“Disclosure Indicator”。

选择Table View,添加Prototype Cell。在“Attributes Inspector”下,把“Prototype Cells”的值从“0”改到“1”。修改完成后,Xcode立刻自动显示prototype cell。我们也把“Style”选项从“Plain”改成“Group”,显示另一个表格风格。

Storyboard-Prototype-Cell

接下来,选择“Prototype Cell”,你应该能够为表格定制风格了。为了让每个表格显示一个提示箭头,把“Accessory”改成“Disclosure Indicator”。定义重用标识符(Reuse Identifier)比较重要。你可以认为它是表格的ID。我们可以针对某个具体的prototype cell使用它。然而,这里定义为“RecipeCell”是为了与代码中的一致。

Storyboard-Edit-Prototype-Cell

现在再次运行应用程序。它看起来又发生了些变化。我们把表的风格改为“Grouped”,并添加了提示箭头。

Storyboard-Recipe-App-with-Disclosure

添加详细视图控制器

终于到了文章最后的部分。显示菜谱详细内容的详细视图控制器(Detail View Controller)还差点儿什么呢?当用户点击菜谱中的任何一项时,详细视图控制器都应该显现。

好了,我们添加一个新的View Controller作为详细视图控制器。

Storyboard-Create-Detail-View-Controller

本文的主要目的是向你展示如果实现Navigation Controller。我们会让详细视图尽量简单,就用一个标签来显示菜名。从对象库里拖拽一个标签,放到视图的中央。你可以修改标签的字体和字号,使标签更好看一些。

接下来,我们添加一个segue来连接prototype cell和新的View Controller。添加segue对象非常简单。按住control键不放,点击prototype cell,将其拖拽到View Controller。

Storyboard-Add-Segue

放开按钮,会天出三种类型的Segue(push,modal和custom)。

Storyboard-Segues

就像前面说的,segue定义了scene之间点连接。标准的导航控制器选择“Push”类型的连接。一旦完成,Xcode会自动使用segue链接两个scene。看起来这个样子:

Storyboard-Segue-Connection

现在再运行一下应用程序。选择任何一项后,应用程序会显示详细视图控制器。虽然详细视图控制器只显示一个标签,但是导航控制器已经起作用了。

Receipe-App-With-Detail-Controller

接下来讲些什么内容?

这是一篇较长的文章,终于完成了!我希望你对Storyboard有了更好的理解,知道如何设计自己的导航控制器。然而,还有一件事情没有讲:如何将菜单的名称从“Recipe Book View Controller”传递到“Detail View Controller”呢?我会在本周末发布一篇文章对此进行介绍。

这些Storyboard,UITableView和Navigation Controller是UI元素的基础,构建iOS应用程序的时候常被用到。所以要花费一些时间来通读本文,确保对此了如指掌。

[转载此篇译文,请注明译文出处]

发表评论

电子邮件地址不会被公开。 必填项已用*标注