iOS 7教程-Storyboards Part1


http://www.tairan.com/archives/5365


站内提示:教程成员Matthijs Hollemans(iOS Apprentice系列的作者)已经发表了这个教程的iOS5版本至iOS7版本。这是本书第三版的预览,这个版本将会更新到iOS 7。好好享受吧!

Storyboarding是一个首次在iOS5中引入的一个优秀特性,它为你节省了大量构建app用户界面的时间。

为了向你展示什么是storyboard,首先看一幅图。下面是在这个教程中你将创建的storyboard。

1

你可能还不知道这个app到底是干什么的,但是你可以清楚的看到它有哪些场景,以及它们是怎么相互关联的.这就是使用storyboards的好处。

如果你有一个带有很多不同场景的app, 那么使用storyboards可以减少从一个场景到另外一个场景的衔接代码。你的app使用一个单独的storyboard,它包含所有这些视图控制器的设计和它们之间的关系,用它来代替每一个视图控制器使用一个独立的nib文件。

Storyboards比起普通的nibs有以下几个优点:

1. 使用一个storyboard你能对你的app有一个所有场景以及它们之间联系的概览。因为整个设计是在一个单独的文件中,而不是分布到一些独立的nibs, 所以很容易了解一切。

2. storyboard描述了各种场景之间的转换。这些转换被叫做“segues”(联线),创建“segues”只需按住ctrl,同时从一个视图控制器拖拽到另一个视图控制器。多亏了segues,让我们能够在UI上写更少的代码。

3. Storyboards通过一个新的原型cells和静态cells特征,使得使用表格视图更容易。你可以完全在storyboard编辑器中设计表格视图,可以节省一些你不得不写的一些代码。

Storyboards教程:iOS 7样式

启动Xcode,然后创建一个新的工程。使用 Single View Application模版创建工程。

2

按照以下模板填写:

• Product Name: Ratings
• Organization Name: 填写你喜欢的。
• Company Identifier: 你的apps使用的标识符, 用反向域名符号。
• Class Prefix: 留空
• Devices: iPhone

使用上个版本的Xcode时,你得在新工程中选择使用storyboards,但是Xcode5不需要这个选项,Xcode5中storyboards是默认开启的。

Xcode创建好工程后,Xcode的主窗口应该是下面这样:

3

新的工程由两个类组成,AppDelegate和ViewController,以及这个教程的核心:Main.storyboard文件。注意在这个工程中没有.xib
文件。

这是个只支持纵屏的app,所以在你继续之前,取消选择Deployment Info下的 Landscape Left 和Landscape Right 选项。

让我们看下storyboard。点击文件列表中的Main.storyboard,然后在Interface Builder中打开:

4

在Interface Builder中编辑storyboards和编辑nibs非常类似。你可以从Object Library(在右下角)拖拽新的控件到视图控制器来设计布局。不同点是storyboard不仅包含一个视图控制器,而是包含所有的。

Storyboards的视图控制器的正式专有名词是“场景”,但是你可以交替使用这两个名称。在storyboards中场景代表视图控制器。准确说你可以为每个场景/视图控制器使用一个单独的nib,但是现在它们都被结合到一个单独的storyboard中。

在iPhone上同一时间只有一个可见场景,但是在iPad上你可以同时显示几个,比如主面板和细节面板在一个分割视图中,或者一个点击弹出视图popover的内容。

注:Xcode 5默认开启了storyboard和nibs文件的Auto Layout自动布局。自动布局是一个很酷的新技术,它可以使用户界面很灵活,可以自动调整大小,这将会在iPad上或者iPhone 5上很有用,但是它只支持iOS6及以上版本系统。并且还需要点功夫去学习,所以本教程中不使用它。参考我们的iOS 6和iOS 7教程来学习更多关于自动布局的知识。

从storyboard的文件查看器中禁掉Auto Layout:

5

为了知道storyboard如何工作的,拖拽一些控件到空白的视图控制器上:

6

找到storyboard画布底部的按钮:

7

点击它来打开左边侧边栏的Document Outline文档大纲 :

8

当编辑一个nib时,这个区域仅仅列出这个nib的组件,但是使用storyboard时,它显示所有视图控制器的内容。当前在storyboard中只有一个视图控制器(或场景),但是随着教程的进行,你将加入其它的一些。

场景下方有一个文档大纲的微型版本,叫做Dock:

9

Dock显示了场景中的顶层对象。每个场景至少有一个视图控制器对象,一个First Responder对象,一个Exit项,但是也有可能有其它顶层对象。Dock对于创建outlets和actions连接很方便。如果你需要连接东西到视图控制器,你只需把这个图标拖到Dock上。

注意:你可能不会经常用到First Responder。这是一个代理对象,适用于任何特定时间有第一响应者状态的任何对象。它也能在你的nib中显示,但你可能没有必要使用它。举个例子,你可以连接从一个按钮连接一个Touch Up Inside到First Responder的剪切selector。如果某时刻一个文本框有输入点,然后你按下按钮,使得现在是第一响应者的文本框的文本剪切到粘贴板。

运行app,现在编辑器中你设计的应该是下面这个样子(在这里显示的是iOS 7,4英寸高清iPhone 模拟器):

10

如果你曾经做过一个基于nib的app,你会知道总会得到一个MainWindow.xib文件。这个nib包含顶层的UIWindow对象,一个App Delegate引用,以及一个或多个视图控制器。当你把app的UI 放到storyboard中时,但是MainWindow.xib不再被使用,那么storyboard是怎样装在到app中的呢?

让我们看一下app的代理,打开AppDelegate.h,它应该是像下面这样的:

#import<UIKit/UIKit.h>
@interface AppDelegate:UIResponder<UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

使用storyboards需要你的application的代理继承UIResponder,并有一个UIWindow属性。如果你看一下AppDelegate.m,你会发现它几乎是空的,所有的方法实际上都是空的,甚至application:didFinishLaunchingWithOptions:也只是简单的返回YES。

秘密在Ratings-Info.plist 文件中,点击Ratings-Info.plist 文件(你可以在Supporting Files组里找到它),如下所示:

11

Storyboard apps使用键UIMainStoryboardFile,或者是“Main storyboard file base name”,来指定storyboard的名字,必须在app启动时载入。当这个设定被保存,UIApplication将会载入命名的storyboard文件,会自动初始化storyboard的第一个视图控制器,然后把它的视图放在一个新的UIWindow对象中,没有编程的必要。

你也可以在工程设置的Deployment Info中看到它。

12

为了完整性,也打开main.m看看里面的东西:

#import<UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char *argv[])
{
  @autoreleasepool{
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  {
}

app代理不是storyboard的一部分,你必须传递app代理类的名字到UIApplicationMain(),否则不能找到它。

添加到我的选项卡

Ratings app有一个包含两个场景的选项卡式界面,用storyboard创建选项卡真的很简单。

切回 Main.storyboard, 从 Object Library拖拽一个Tab Bar Controller到画布。你可能想要首先最大化Xcode窗口, 因为Tab Bar Controller 带来了两个视图器,你需要一些空间来操作。你可以使用画布右下角的浮动面板放大。

13

新的Tab Bar Controller提前配置好了其它两个视图控制器,每个页面一个。UITabBarController就是所谓的做容器(container) 视图控制器,因为它包含一个或多个其它的视图控制器。两个其它的常见的容器是Navigation控制器和分割视图控制器(你呆会看到它们)。

容器关系由Tab Bar Controller和它包含的视图控制器之间的箭头来表示。

14

注:如果你想要把Tab Bar Controller和它连接的视图控制器作为整体移动,你可以按住⌘,选择多个场景,然后一起移动(选中的场景有粗蓝的外框)

拖拽一个label文本标签到第一个视图控制器,文本设为“First Tab”,同样拖拽一个文本标签到第二个视图控制器,命名为“Second Tab”,这会在切换选项时让你确切的看到发生了什么。

注:当编辑器被放大时你不能拖拽东西到场景中,你需要首先返回正常缩放等级,你可以通过双击场景达到这个目的。

选择Tab Bar Controller,打开属性查看器,勾上Initial View Controller.

15

在面板中先前指向普通的视图控制器的箭头现在指向Tab Bar Controller:

17

这意味着当你运行 app时, UIApplication将会使Tab Bar Controller成为主屏幕. Storyboard总会有一个单独的视图控制器指定成为initial view controller, 它将作为storyboard的入口。

提示:改变初始的视图控制器,你也可以拖拽视图控制器的箭头。

运行app,现在app有一个分页栏,你可以用选项卡来切换两个视图控制器:

18

Xcode实际上带了一个创建选项卡式 app的模版(不要惊讶它被叫做Tabbed Application)可以使用,但是最好要知道是怎样工作的,所以你可以也动手创建一个Tab Bar Controller。

注:如果你连接超过五个场景到Tab Bar Controller,当你运行app时它会自动得到一个More…的栏,非常可爱!

移除模版最先添加的视图控制器,因为你不再需要使用它。现在storyboard仅仅包含分页栏和两页的场景。

添加一个表格视图控制器

两个连接到Tab Bar Controller的场景都是普通的UIViewControllers,你将用一个UITableViewController代替第一个分页场景。

点击第一个视图控制器来选择它,然后删除它。从Object Library拖拽一个新的Table View Controller到先前场景过去的位置:

19

选择Table View Controller, 选择Xcode菜单栏的 Editor\Embed In\Navigation Controller,这将添加另外一个视图控制器到画布:

20

你也可以从Object Library中拖拽一个Navigation Controller导航控制器,但是上述方法会更简单。因为Navigation Controller也是一个容器视图控制器(就像是Tab Bar Controller),它也有一个关系箭头指向表格视图控制器,你也可以在文档大纲中看到这些关系:

21

注意嵌入表格视图控制器给了它一个导航条。Interface Builder自动放置在那里,因为现在场景会显示在导航控制器的框架中。它不是一个真的UINavigationBar对象,而是一个模拟的。

如果你查看表格视图控制器的属性查看器,你将会在顶部看到Simulated Metrics:

22

“Inferred”是storyboards的默认设置,它意味场景在一个导航控制器里时显示一个导航条,当它在一个Tab Bar Controller时显示一个分页栏,等等。如果你想要你可以覆盖这些设置,但是记住这儿它们只是帮助你设计屏幕,在运行时Simulated Metrics不能使用;它们只是一个可见的设计助手,显示你的屏幕最终的样子。

让我们连接这两个场景到Tab Bar Controller.按住Ctrl,拖拽Tab Bar Controller到导航控制器:

23

当你松开, 一个小弹窗菜单出现了:

24

选择Relationship Segue – view controllers 选项,这给两个场景创建了一个新的关系箭头:

25

Tab Bar Controller有两个这样的关系,每页一个。导航控制器自己有一个关系连接到表格视图控制器,这也是另外一种箭头类型,联线,我们呆会讨论。

当你做好了新连接,一个新页被加到Tab Bar Controller,简单的命名为“Item”. 对于这个app,你想要这个新场景作为第一页,所以拖拽tabs来改变它们的顺序:

26

运行app,现在第一页包含一个导航控制器的表格视图。

27

在你放入一些实际的功能前,让我们清理下storyboard,你将第一页命为“Players”,第二页为“Gestures”。不像你可能期望的,你不会改变Tab Bar Controller本身,但是是去改变连接到这些tabs的视图控制器。

一旦你连接一个视图控制器到Tab Bar Controller, 它就被赋予了一个Tab Bar Item对象。你使用Tab Bar Item来配置tab的标题和图像。

选择导航控制器里的Tab Bar Item,在属性查看器中设置标题为Players:

28

将第二页试图控制器的Tab Bar Item重命名为Gestures.

一个设计良好的app应该在页面上放一些图片。这篇教程的资源包含一个名字为Images的子文件夹,把这个文件夹加到工程中。在Player的Tab Bar Item的属性查看器中,选择Players.png。你可能已经猜到了,给Gestures设置图像Gestures.png。

一个嵌在导航控制器的视图控制器有一个Navigation Item用来配置导航条。选择表格视图控制器的Navigation Item(你可以在文档大纲中找到),在属性查看器中将它的标题改为Players。

你也可以选择双击导航条,在这里改变标题。(注:你应该双击在表格视图控制器中模拟的导航条,而不是导航控制器中真正的导航条对象)

29

运行app,对你漂亮的tab bar感到惊奇,没有写一行代码!

30

cells 原型

Cells原型可以让你很容易地在storyboard编辑器内为你的表格视图cells设计自定义布局。表格视图控制器带来了一个空白的cell原型。点击选择cell,在属性查看器中设置Style选项为Subtitle,这样做立刻就使cell包含两个labels。

如果你以前用过表格视图,你动手创建过自己的cell,你可能会记得这是UITableViewCellStyleSubtitle样式。使用cells样本,你可以选择你刚刚做的那样的内建样式,或者创建你自己的自定义设计(你很快会这么做)。

设置Accessory属性为Disclosure Indicator,在Identifier中填入PlayerCell. 所有的cells样本仍旧是普通的UITableViewCell对象,因此应该有一个重用的标识符。

31

运行app,什么都没有变化,这没什么好奇怪:你仍旧需要为表格设定一个数据源,这样它才知道每行显示什么内容。

加入一个新的文件到工程,选择Objective-C class模版。命名为PlayersViewController,使其为UITableViewController的子类,“With XIB for user interface”选项应该不要勾选,因为你要在storyboard中设计视图控制器,今天没有nibs!

32

回到storyboard,选择表格视图控制器(确保选择真正的视图控制器,而不是里面的视图之一)。在Identity查看器中,设置Class为PlayersViewController。这是连接storyboard中的场景和你自己的视图控制器子类必要的一步。不要忘记这一点,否则你的类不能被使用!

33

现在当你运行app时storyboard的表格视图控制器就是PlayersViewController类的实例。

加一个可变的数组属性到PlayersViewController.h:

#import <UIKit/UIKit.h>
@interface PlayersViewController:UITableViewController
@property (nonatomic,strong) NSMutableArray *players;
@end

这个数组包含app的主要数据模型-一个包含Player对象的数组。用Objective-C class模版添加一个新的文件。命名为Player,NSObject的子类。修改Player.h如下:

@interface Player: NSObject

@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *game;
@property (nonatomic,assign) int rating;
@end 

这里没有什么特别的,Player是一个简单的container对象,三个属性:玩家的姓名,他玩的游戏,一个1到5的星。

你将在App代理中创建一个数组,存放一些测试玩家对象,给这些对象赋值PlayersViewController的player属性。

在AppDelegate.m中,在文件开头import Player文件和PlayersViewController类,添加一个新的实例变量命名为_players:

#import "AppDelegate.h"
#import "Player.h"
#import "PlayersViewController.h"

@implementation AppDelegate
{
  NSMutableArray *_players;
}
// Reset of file...

然后,按如下修改application:didFinishLaunchingWithOptions:方法:

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   _players = [NSMutableArray arrayWithCapacity: 20];
   
   Player *player = [[Player alloc] init];
   player.name = @"Bill Evans";
   player.game = @"Tic-Tac-Toe";
   player.rating = 4;
   [_player addObject: player];

   player = [[Player alloc] init];
   player.name = @"Oscar Peterson";
   player.game = @"Spin the Bottle";
   player.rating = 5;
   [_player addObject: player];

   player = [[Player alloc] init];
   player.name = @"Dave Brubeck";
   player.game = @"Texas Hold'em Pocker";
   player.rating = 2;
   [_player addObject: player];

   UITableBarController *tableBarController = (UITableBarController *) self.window.rootViewController;
   UINavigationController *navigationController = [tableBarController viewControllers][0];
   PlayersViewController *playersViewController = [navigationController viewControllers][0];
   playersViewController.players = _players;

   return YES;
   
}

上面代码简单地创建一些Player对象,然后添加到_players数组,看看接下来的代码:

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [tabBarController viewControllers][0];
PlayersViewController *playersViewController = [navigationController viewControllers][0];
playersViewController.players = _players;

呀,这是什么?!你想要把PlayersViewController的players属性添加到_players数组中,这样我们可以用这个数组做数据源,但是app的代理不知道PlayersViewController,所以它不得不通过storyboard找到它。

注:这是storyboards的一个限制,用nibs你在MainWindow.xib会有一个到App delegate的引用,你可以对顶层的视图控制器和App delegate的outlets做连接,而storyboards则不可能,你不能做从顶层视图控制器到app delegate的引用。这很不幸,但是你总是可以用编程的方式得到这些引用,就是你在这里所做的。

让我们一步步的看:

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;

你知道storyboard的初始视图控制器是一个Tab Bar Controller,所以你可以查找window的rootViewController,将其转成UITabBarController.

PlayersViewController位于第一页的导航控制器里,所有首先你找到UINavigationController对象,

UINavigationController *navigationController = [tabBarController viewControllers][0];

然后请求它的root view controller,正是你要找的PlayersViewController:

PlayersViewController *playersViewController = [navigationController viewControllers][0];

通过storyboard来得到你想要的视图控制器需要一点努力,但是这就是方法。当然,如果你改变了tabs的顺序,或者是一个Tab Bar Controller不是一个主视图控制器的app,你就要修改逻辑了。

既然你有一个包含Player对象的数组,你可以继续为PlayersViewController构建数据源。打开PlayersViewController.m,在顶部添加一个import:

#import "Player.h"

按如下修改表格视图的数据源方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   return [self.players count];
}

真正的工作是在 cellForRowAtIndexPath. 很显然, 这个方法应该是像下面这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *CellIdentifier = @"Cell";

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                     reuseIdentifier:CellIdentifier];
   }

   // Configure the cell...
   return cell;
}

你可以请求表格视图弹出一个cell,如果返回为空,因为没有空闲的cell重用,你将创建一个新的cell类实例。

用以下代码替换方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PlayerCell"];

   Player *player = (self.players)[indexPath.row];
   cell.textLabel.text = player.name;
   cell.detailTextLabel.text = player.game;

   return cell;
}

这看起来更简单了!你需要做的唯一事情是得到一个新的cell:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PlayerCell"];

如果不存在可以循环的cell,它将会自动创建一个cell样本的copy,返回给你。你所要做的是提供重用的在storyboard cell样本设置的标识符,在这个例子中是PlayerCell. 不要忘记设置标识符,否则这个小方案不能工作!

34

使用这些新式的cell样本只需一行代码,这很棒!

注:在这个app中你只使用了一个cell样本,但是如果你的表格需要显示不同种类的cells,你可以简单地添加额外的cells样本到storyboard。你可以复制存在的cell来创建一个新的,或者递增表格视图cell样本的属性值,但是记住给每个cell不同的重用标识符。

设计你自己的Cells原型

对一些apps来说用一个标准的cell样式是可以的,但是这个app你想要在cell的右边添加一个图像,来显示玩家的评分(一到五星)。标准cell样式不支持image view,所以我们不得不做自定义设计。

切回Main.storyboard,在表格视图中选择cell样本,将Style属性设为Custom,默认的label消失了。

首先让cell高一点,既可以通过在底部拖拽,也可以在Size查看器中改变Row Height值。使得cell高55点。

从Objects Library拖两个Label对象到cell,把它们放在大致先前标准labels的位置,挑选你喜欢的颜色设置字体和颜色。

拖拽一个Image View到cell,放到右边,挨着详情指示,将其设为81点宽;高度很重要,设置Mode为Center(在属性查看器的View下面),这样,无论你放进什么图像,都不会被拉伸。

使得labels 190点宽,这样它们不会被image view覆盖。Cell样本的最终设计应该是下面这个样子:

35

因为这是一个自定义设计的cell,你不再需要使用UITableViewCell的textLabel和detailTextLabel属性来放置文本到labels中。这些关于labels的属性不再需要了,它们只在标准cell样式中有效。但是,你将需要tags来找到labels。

Name label 设置tag为100,设置Game label tag为101,Image View的tag设为102,你可以在属性查看器中做这些事情。

然后打开PlayersViewController.m,添加一个新的方法, imageForRating:

- (UIImage *)imageForRating:(int)rating
{
   switch (rating) {
       case 1: return [UIImage imageNamed:@"1StarSmall"];
       case 2: return [UIImage imageNamed:@"2StarsSmall"];
       case 3: return [UIImage imageNamed:@"3StarsSmall"];
       case 4: return [UIImage imageNamed:@"4StarsSmall"];
       case 5: return [UIImage imageNamed:@"5StarsSmall"];
   }
   return nil;
}

用以下代码修改tableView:cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PlayerCell"];

   Player *player = (self.players)[indexPath.row];

   UILabel *nameLabel = (UILabel *)[cell viewWithTag:100];
   nameLabel.text = player.name;

   UILabel *gameLabel = (UILabel *)[cell viewWithTag:101];
   gameLabel.text = player.game;

   UIImageView *ratingImageView = (UIImageView *)[cell viewWithTag:102];
   ratingImageView.image = [self imageForRating:player.rating];

   return cell;
}

现在再次运行app,它应该是下面这个样子:

36

嗯,这看起来不太对,cells覆盖了前面的。你确实改变了cell样本的高度,但是表格视图没有使之生效。有两种方法来解决:你可以改变表格视图的Row Height属性,或者实现tableView:heightForRowAtIndexPath:方法,前者更容易,让我们这样做。

注:如果你事先不知道cells的高度,你可以使用heightForRowAtIndexPath,或着不同的行用不同的高度。

回到 Main.storyboard, 在表格视图的Size查看器中, 设置Row Height 为 55:

37

38

顺便说一下,如果你先前是通过手动拖拽而不是输值来改变cell的高度,这样表格视图的Row Height会自动改变,第一次的时候可能运行的是正确的。

使用一个Cell子类

表格视图已经工作非常好了,但是我不是使用tags来访问labels和其它cell样本子视图的狂热粉丝,如果你可以连接这些labels到outlets,然后使用相应的属性会非常方便。结果是,你可以。

添加一个新的文件到工程中,使用Objective-C class模版,命名为PlayerCell,使其为UITableViewCell的子类。

修改PlayerCell:

@interface PlayerCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *nameLabel;
@property (nonatomic, weak) IBOutlet UILabel *gameLabel;
@property (nonatomic, weak) IBOutlet UIImageView *ratingImageView;

@end

这个类本身没有做很多事情,仅仅添加nameLabel, gameLabel和ratingImageView属性,所有的都是IBOutlets.

回到IBOutlets.选择cell样本,在Identity查看器中修改Class为PlayerCell。现在无论你什么时候用dequeueReusableCellWithIdentifier:向表格视图请求一个新的cell,它会返回一个PlayerCell实例,而不是一个常规的UITableViewCell.

注意你给这个类名和重用标识符同样的名字-它们都叫做PlayerCell —但是这仅仅是因为我喜欢使事情一致。类名和重用标识符与其它无关,所以你可以按你想的来命名。

现在连接labels和image view到这些outlets,选择label,从它的Connections查看器中的New Referencing Outlet拖拽到表格视图的cell,分别选择nameLabel和gameLabel。

39

重要:你应该连接控件到表格视图的cell,而不是视图控制器!你可以看到,无论你的数据源什么时候用dequeueReusableCellWithIdentifier向表格视图请求一个cell,表格视图不会给你真正的cell样本,而仅仅是一个copy(或者是之前cells之一循环可用)

既然你已经连接了属性,你可以再一次简化数据源代码。首先在PlayersViewController.m导入PlayerCell类

#import "PlayerCell.h"

将dequeueReusableCellWithIdentifier改成:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   PlayerCell *cell = (PlayerCell *)[tableView dequeueReusableCellWithIdentifier:@"PlayerCell"];

   Player *player = (self.players)[indexPath.row];
   cell.nameLabel.text = player.name;
   cell.gameLabel.text = player.game;
   cell.ratingImageView.image = [self imageForRating:player.rating];

   return cell;
}

这才像话,现在你将从dequeueReusableCellWithIdentifier收到的对象转换成PlayerCell,然后你可以简单的使用这些连通labels和image view的属性。使用cells样本使得表格视图整洁多了不是吗?

何去何从?

查看教程的第二部分,那里我们谈到了联线,静态表格视图cells,添加Player的场景,一个游戏选择的场景,还有这个教程可下载的示例教程。

iOS 7系列中的Storyboards初级教程是我们的 iOS 5 教程 书的其中一张的更新预览。如果你喜欢,查看这本书-有关于中级storyboarding的完整的第二章节,大于我们在这里免费提供的!我们也在将我们的书更新导iOS最新的版本iOS 7,快要出版了。

如果你感到在教程中有任何不明白的,你可能想要复习下我们新出版的 iOS Apprentice系列的基础知识。在这个系列中,我谈到了作为一个从头开始的iOS开发者你需要的基础知识-特别适合完全的初学者,或者那些想要填充某些空白的人。

如果你有关于storyboarding的任何问题或评论,请加入下面的论坛讨论!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值