首页 > 其他分享 >在iOS 7中使用storyboard(part 1)

在iOS 7中使用storyboard(part 1)

时间:2022-12-27 18:38:37浏览次数:64  
标签:控制器 storyboard iOS 视图 cell Controller part tab


Storyboard是一项令人兴奋的功能,在iOS5中首次推出,在开发app的界面时可以极大地节省时间。



 



如下图所示,这就是一个完整的应用的storyboard,接下来我们要学习如何通过这种方式创建应用。



 





现在你可能还不是很精确地知道我们的应用可以做什么,但是通过上图,我们可以很清晰的明白这些视图之间的关系。这就是使用storyboard的强大之处。


 


当你的应用有许多不同页面的时候,通过使用storyboard,可以大大减少页面之间跳转的代码。过去我们为每个视图控制器创建一个nib文件,现在,只需要使用一个storyboard,它包含了你应用中所有的视图控制器以及它们之间的关系。


 


相比传统的nib文件,storyboard有很多优点:


1.使用storyboard,可以更好地理解应用中所有视图在概念上的概览以及它们之间的关系。掌控所有的视图变得很容易,因为所有的设计都是在一个文件中,而不是在很多单独的nib文件中。


2.storyboard描述了视图之间的动画,这些动画叫做"segues"你可以很容易的通过从一个视图控制器(点ctrl-dragging)拖拽到另一个来实现,感谢"segues"让我们不需要写代码去控制页面跳转了。


3.storyboard通过新的cell原型,以及静态cell的特性,让表格控制器实现起来更容易了。你近乎可以完全的通过storyboard来设计你的表格控制器,这也大大的减少了你不得不写的代码量。.


 


并不是所有的都是那么完美,当然使用storyboard也是有一些限制的,storyboard的Interface builder 远没有旧版nib编辑器那么强大,并且有一些东西只能在nib中做而不能在storyboard编辑器中做。还有,你需要一个大号的显示器,尤其是在开发iPad应用的时候。


 


如果你是那种不喜欢用Interface builder 画界面而是用代码直接写界面的人,很遗憾,storyboard并不适合你。就个人而言,我比较倾向于写的代码越少越好,特别是控制UI的那种,所以storyboard简直就是为我准备的一把利器。


 


当然了,如果你想继续使用nib,那么继续用好了,你需要知道的是你可以通过storyboard来绑定各视图控制器,对于使用storyboard,还是旧版的nib,不是一个非做选择不可的事,随你好了。


 


在这个例子中,我们将会学到--通过storyboard我们可以做什么,我们将会创建一个简单的应用,功能大致是有一个现实玩家,游戏,以及玩家技能评分的这么一个列表。在学习过程中,你几乎可以学到大多数通过故事板可以做到的事。


 


storyboard教程 : iOS 7 版


打开Xcode创建一个新项目,这里我们用 Single View Application 模板:




按照下面的方式填写模板中的选项:


1.Product Name: Ratings


2.Organization Name: 随便写点什么都行


3.Company Identifier:域名反过来写,例如com.xx.xx


4.Class Prefix: 空着就行


5.Devices: iPhone


 


用旧版Xcode的时候你需要特别指定下这个新项目是用storyboard的,但XCode5之后,不再有这个选项了,默认就是用storyboard创建的项目。


 


在Xcode创建完项目之后,Xcode的主界面上应该如下图所示:




AppDelegate 和  ViewController, 以及我们这个例子中的明星:  Main.storyboard 文件. 请注意,这个项目中并没有xib文件。


 


Deployment Info, Device Orientation下面的 Landscape Left和Landscape Right 选项。


 


接下来让我们看一下storyboard,点击列表中的 Main.storyboard 在interface builder中打开它。




在Interface builder中编辑storyboard就跟编辑nib文件差不多,你可以从Object Library中拖拽新的元素到视图控制器中,并且可以编辑它的布局。区别在于storyboard不仅仅有一个视图控制器,它把你应用中的所有视图控制器全都包含了。


 


按标准的storyboard的说法,一个视图控制器就是一个"场景"。你可以交替的使用这个模式,"场景"是呈现在storyboard中的视图控制器,以往,你可能为每一个"场景"/视图控制器创建一个nib文件。现在你只需要把他们都集中在一个storyboard里。在iPhone中,一次只能看到一个场景,而iPad应用中,一次可能会看到多个。例如"master/detail "或者 "popover"


 


注意: Xcode 5默认storyboard以及nib中的 Auto Layout属性是打开的。 Auto Layout 是一个新的很帅气的可以自动调整控件大小的这么一个技术,在应用适配iPad以及iPhone5的时候尤其有用,可惜它只能在 iOS 6 以上运行。当然了,它也需要一定的学习曲线,这个例子中我们不会详细的说这点。如果你有兴趣了解 Auto Layout,请参阅我们的书籍《 iOS 6 by Tutorials andiOS 7 by Tutorials》.


 


在storyboard中的File inspector  禁用Auto Layout选项,如下图:




拖拽一些控件到空的视图控制器上,感受一些storyboard编辑器是如何工作的。




在storyboard编辑页面中找到下面这个标上红色左箭头的按钮




点击它打开左侧的 Document Outline 视图




当编辑nib的时候,列表中显示的是这个nib中所有的控件,但对于storyboard,它会显示你的应用中的所有视图控制器的内容。上图只有一个视图控制器,在接下来的例子中,我们会增加其他的。


 


在scene下面有微型版的Document Outline,叫做Dock, 如下图:




什么是 Dock ?


它显示了当前视图的最上层对象,每个视图都至少有一个View Controller 对象,一个First Responder 对象,一个Exit 项目。当然了,它也可能会有其他的最上层对象。使用Dock 去连接outlets 和 actions变的非常容易,当你想把某个对象连接到视图控制器中时,只需简单地把它的图标拖拽到Dock上。


 


注意: 你很可能没怎么用过First Responder。这是指任何物体在任何给定时间具有第一响应状态的代理对象。它一直在你的nib中,你很可能从来没有必要使用它。举个例子,按钮中有个Touch Up Inside事件,把它拖给First Responder的 cut: selector。如果在某一点的文本字段具有输入焦点,那么你可以按下该按钮,使文字栏位,也就是现在的第一响应者,切其文本到剪贴板。


 


运行该app,它看起来应该和你在编辑器中设计的一样(此处使用了运行iOS 7的4-inch Retina iPhone simulator):




如果你写过以nib为基础的应用,通常会有一个叫做MainWindow.xib的文件。这个文件有一个UIWindow对象指向App Delegate,以及其他视图控制器。当你想用storyboard做这些的时候,就不需要MainWindow.xib了。那么storyboard是如何加载到应用中的呢?


 


让我们看看应用的 application delegate。 打开 AppDelegate.h,看起来应该是这样:


 


  1. #import <UIKit/UIKit.h> 
  2.   
  3. @interface AppDelegate : UIResponder <UIApplicationDelegate> 
  4.   
  5. @property (strong, nonatomic) UIWindow *window; 
  6.   
  7. @end 

 


UIResponder,并且有一个 UIWindows 属性。下面打开 AppDelegate.m,这里设么都没有,所有的方法都是空的,甚至 application:didFinishLaunchingWithOptions:


 


Ratings-Info.plist


 


UIMainStoryboardFile 或者" Main storyboard file base name" 来指定当应用启动的时候,哪一个storyboard是必须被加载的。当设置生效, UIApplication会自动加载叫这个被命名的storyboard文件,并把它第一个视图控制器显示到 UIWindow中。这些都不必写代码去实现。这些你还可以通过修改  Project Settings下面的 Project Settings来实现,如下图:


 


出于完整性, 打开 main.m 如下图:


 


  1. #import <UIKit/UIKit.h> 
  2.  
  3. #import "AppDelegate.h" 
  4.   
  5. int main(int argc, char *argv[]) 
  6.     @autoreleasepool { 
  7. return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 
  8.     } 

 


UIApplicationMain() 否则,应用就会找不到它。


 


把它加到标签上 


 


这个Ratings 应用是由标签控制的2个视图 ,使用storyboard,创建标签很容易。


 


Main.storyboard, 把一个Tab Bar Controller 从Object Library 拖到面板中。你可能需要最大化你的XCode,因为Tab Bar Controller 默认会带 2个视图控制器,你需要能完整的看到他们,通过右下角的小浮动窗口,可以缩小这个面板。




 


一个新的Tab Bar Controller 默认会带2个视图管理器,一个标签一个。UITabBarController也被叫做容器视图控制器,因为一般它都会包含一个以上的视图控制器。此外还有其他两种容器控制器:Navigation Controller和the Split View Controller。


 


容器控制器通过箭头管理它的视图,如下图




 


注意: 如果你想把Tab Bar Controller 的所有视图一起移动,你需要点?-click选中这些视图,然后再移动他们(被选中的视图会有一个蓝色的下划线)。


 


在第一个视图控制器中拖入一个label并且设置它的text 为 "First Tab",同理,在第二个视图管理器中加入"Second Tab" 这可以让你看到标签切换后会发生什么情况。


 


注意:


 


 Attributes inspector。选中那一栏指的是  Initial View Controller。如下图:




 


在画布上,先由一个箭头指向Tab bar controller




 


UIApplication 会把Tabbarcontroller 作为主控制器。storyboard同伴有一个独立的视图控制器,他是特定的" initial view controller", 它是storyboard的切入点。


 


提示: 改变 initial view controller ,你可以通过拖拽在视图控制器之间的箭头。


 


运行应用试试吧,现在应用的效果是有一个tab bar 并且可以通过tab 去切换视图。如下图:




Xcode 可以创建一个以tab为模板的项目(Tabbed Application template) ,你以前应该用过, 最好理解下它是如何工作的,如果非手动创建,也不至于手足无措。


 


注意: 当你想Tabbarcontroller 中加入超过5个视图的时候,它会自动的生产一个 More的tab。


 


删除模板自带的那个视图控制器,现在storyboard中只有一个tab bar 以及两个tab各自对应的一个视图。


 


添加一个Table View Controller


 


两个scene隶属的Tab Bar Controller都是标准的 UIViewControllers,下面我们用UITableViewController 替换掉 第一个tab 中的scene。


 


Table View Controller 到先前被删除的scene所处的位置。如下图:




Editor\Embed In\Navigation Controller ,现在另一个视图控制器被加到画板中了:




你还需要从Object Library中拖一个Navigation Controller,但这种嵌入在命令行中一样简单。


 


因为Navigation Controller 也是一个容器视图控制器(跟Tab Bar Controller一样), 它有一个关系箭头指向Table View Controller,你还可以在 Document Outline看到这个关系:




注意:嵌入Table View Controller给了它一个navigation bar,Interface Builder 自动加上它的,因为当前视图会显示在Navigation Controller的frame里。它并不是一个真的UINavigationBar ,只是一个模拟的。


 


Attributes inspector, 你会看到上方有 Simulated Metrics 选项,如下图:




"Inferred" 作为storyboards的默认值,它意味着视图将会显示一个navigation bar,当它处于Navigation Controller中时,显示一个tab bar 当它处于Tab Bar Controller中时。你可以修改这些默认设置,但是注意,这里只是方便你设计用的,"Simulated Metrics"并不会在运行时出现,他们是指一个虚拟的设计,用来展示你的视图最终会是什么样子。


 


把这两个视图连接到Tab Bar Controller,按Ctrl-drag 从 the Tab Bar Controller 到 the Navigation Controller如下图:




松手的时候, 出现一个弹出窗口如下图:


 




选择 Relationship Segue - view controllers,它为2个视图创建了一个关系箭头如下图:




Tab Bar Controller有2个关系, 给每个tab都有一个。Navigation Controller自己有一个关系指向Table View Controller。还有另一种类型的箭头"segue" 稍后我们会讲到它。


 


创建完这个新的连接后,一个新的tab 添加到 Tab Bar Controller了, 简单的命名为 "Item"。对于这个应用,你希望这个新视图作为第一个tab,所以拖动tabs,改变他们的顺序如下图:




 


运行应用,第一个tab显示了一个包含在navagationcontroller 下面的 table view,如下图:




在你为应用添加具体的功能之前,让我们先整理下storyboard,分别把第一个tab 第二个tab 命名为  "Players" 和"Gestures"。并不像你期望的那样,你不能在Tab Bar Controller 上改动,只可以在tab 指向的那个视图控制器上做。


 


一旦你把一个视图控制器连上了Tab Bar Controller,它默认会给一个 Tab Bar Item 对象。用这个Tab Bar Item 去改变tab的名字跟图片。


 


选中Navigation Controller里的Tab Bar Item ,在Attributes inspector中把title 设置为 Players,如下图:




同理把第二个tab 设置为 Gestures.


 


一个设计良好的应用需要在tab 上有图标。 这里例子代码中 有个Images 的文件夹在 resource 文件夹下 把这个文件夹加入到项目中 ,选中Players Tab Bar的 Item的 Attributes inspector ,把 Players.png 填进去. 同理处理 Gestures item the 图片为 Gestures.png.


 


一个嵌入在Navigation Controller  的视图控制器有一个 Navigation Item,它是用来配制navigation bar的。在Table View Controller 中选中Navigation Item (在Document Outline可以找到)在 Attributes inspector 中把title改成  Players.


 


此外, 你可以双击navigation bar 直接修改title. (注意: 你需要双击table view controller 中的simulated navigation bar,并不是Navigation Controller 中的真正的那个Navigation Bar 对象),如下图  




运行应用,看看这令人惊叹的tab bar吧,这一切,一行代码都不用写喔~




Prototype cells


 


Prototype cells 允许你在storyboard编辑器中直接为table view 设计自定义cell。


 


UITableViewCellStyleSubtitle


 


Disclosure Indicator




运行应用…什么都没变?这并没有什么值得奇怪的,你还需要为 这个tableview 指定一个data source,这样它才会知道显示什么。


 


Objective-C class 模板,命名为  PlayersViewController ,并且确保它是 UITableViewController 的子类。不要选中With XIB for user interface 选项,因为你已经在storyboard中设计好它了,如下图:


 


回到storyboard选择Table View Controller (确保你只选择了 tableviewcontroller 并没有其他的view 包含在内)。在 Identity inspector中设置它的 Class 为 PlayersViewController. 这对于在storyboard中使用你自己定义的 视图控制器的类很重要,因为如果你不这么做,你的类永远都不会被使用!如下图:




PlayersViewController


 


 mutable array property 到  PlayersViewController.h:


 


  1. #import <UIKit/UIKit.h> 
  2.   
  3. @interface PlayersViewController : UITableViewController 
  4.   
  5. @property (nonatomic, strong) NSMutableArray *players; 
  6.   
  7. @end 

 


该数组将会包含你的应用中的主要数据模型,一个数组包含 Player 对象。使用Objective-C class模板在项目中添加一个新文件,命名为Player, 继承自 NSObject.


 


Player.h 改成下图的样子:


 


  1. @interface Player : NSObject 
  2.   
  3. @property (nonatomic, copy) NSString *name; 
  4. @property (nonatomic, copy) NSString *game; 
  5. @property (nonatomic, assign) int rating; 
  6.   
  7. @end 

 


 


这并没有什么特别的. Player  是一个简单的容器对象包含三个属性:玩家名字,游戏名字,他游戏的评级(1-5星)。


 


Player 对象,并且把它分配给 PlayersViewController的 players 属性。


 


AppDelegate.m中,在文件顶部为 Player和 PlayersViewController添加#import ,并且添加一个实例变量  _players


 


  1. #import "AppDelegate.h" 
  2. #import "Player.h" 
  3. #import "PlayersViewController.h" 
  4.   
  5. @implementation AppDelegate  
  6.     NSMutableArray *_players; 
  7.   
  8. // Rest of file... 

 


修改 application:didFinishLaunchingWithOptions: 方法,如下图


 


  1.   
  2. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
  3.     _players = [NSMutableArray arrayWithCapacity:20]; 
  4.   
  5.     Player *player = [[Player alloc] init]; 
  6. "Bill Evans"; 
  7. "Tic-Tac-Toe"; 
  8.     player.rating = 4; 
  9.     [_players addObject:player]; 
  10.   
  11.     player = [[Player alloc] init]; 
  12. "Oscar Peterson"; 
  13. "Spin the Bottle"; 
  14.     player.rating = 5; 
  15.     [_players addObject:player]; 
  16.   
  17.     player = [[Player alloc] init]; 
  18. "Dave Brubeck"; 
  19. "Texas Hold’em Poker"; 
  20.     player.rating = 2; 
  21.     [_players addObject:player]; 
  22.   
  23.     UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController; 
  24.     UINavigationController *navigationController = [tabBarController viewControllers][0]; 
  25.     PlayersViewController *playersViewController = [navigationController viewControllers][0]; 
  26.     playersViewController.players = _players; 
  27.   
  28. return YES; 

 


我们创建了一些 Player 对象并且把它们加到了 _players 数组中,接下来:


 


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

 


_players array 分配给 PlayersViewController 的  players property,那样它才能把这个数组作为它的data source,但是 app delegate并不知道  PlayersViewController是什么玩意,它会通过storyboard找到它。


 


注意:这是storyboard的一个限制。用nib的时候你需要在App Delegate 中指定MainWindow.xib 的引用,你可以通过连接顶层的视图控制器到你的App Delegate中。在storyboard里,这是不可能的,你不能在app delegate中为你的顶层视图控制器做引用,这很不幸,所以我们一般都手动的写,就像你现在做的这样。


 


让我们一步一步来


 


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

你知道 storyboard最初的view controller 是一个Tab Bar Controller,所以你可以指定window的rootViewController 为 UITabBarController.


 


在第一个tab中,PlayersViewController位于navigation controller,所以你首先要查询UINavigationController 对象,代码如下:


 


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

然后获取它的root view controller, 这里是PlayersViewController:


 


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

为storyboard制作你想要的视图控制器看来是需要花一些时间的,当然了,如果你想换tab的顺序,或者当前应用不是以tab bar controller 作为 rootviewcontroller了,你将不得不修改这个逻辑。


 


现在我们有了一个包含Player对象的数组了,我们可以为PlayersViewController创建datasource了。打开PlayersViewController,在顶部添加import:


 


  1. #import "Player.h" 

修改 table view data source 方法如下


 


  1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
  2. return 1; 
  3.   
  4. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
  5. return [self.players count]; 

 


真正的操作发生在cellForRowAtIndexPath 中,起初方法如下:


 


  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  2. static NSString *CellIdentifier = @"Cell"; 
  3.   
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
  5. if (cell == nil) { 
  6.         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
  7.                                       reuseIdentifier:CellIdentifier]; 
  8.     } 
  9.   
  10. // Configure the cell... 
  11. return cell; 

 


nil


 


  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  2. "PlayerCell"]; 
  3.   
  4.     Player *player = (self.players)[indexPath.row]; 
  5.     cell.textLabel.text = player.name; 
  6.     cell.detailTextLabel.text = player.game; 
  7.   
  8. return cell; 

 


 


这看起来很简单,你只需要像下面获取cell


 


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

如果当前没有一个可以重用的cell 它会自动返回一个prototype cell 的copy 并且返给你。下面你就需要使用在storyboard编辑器中设置的re-use identifier,这里是"PlayerCell"


运行应用,table view如下图所示:




仅仅需要一行代码就可以实现这个新奇的prototype cells。


 


注意:这个应用我们只用到了一种prototype的cell,如果你想用更多种类的cell,只需要简单地把那些额外的prototype cell 加到storyboard上,你也可以复制当前存在的cell 去做一个新的,或者增加当前table view 的Prototype cell的属性,但是要确保一点,每个cell都需要有一个只属于它自己的re-use identifier


 


设计你自己的Prototype Cells


 


很多app 都是使用 默认的cell style的,但是对于这个应用,cell 的右侧有一个图片用来显示这个用户的得分(从1星到5星),默认的cell不带这种具有image的style,所以这里我们需要自己设计一个。


 


Main.storyboard,选择table view 中的prototype cell并把它的Style attribute 设置为 Custom,默认的labels 现在没有了。


 


Row Height值都可以。 把cell的高度设置为55 points。从Objects Library 拽2个 Label 到cell 上, 把他们放在刚才那个label 所在的地方,随便改改颜色 字图或者写点什么都行。


 


Image View 到cell 上,并让它居于cell的右侧,紧挨着disclosure indicator 设置它的Mode 为 Center (在Attributes inspector的view 下面),这样无论你防止什么样的图片到这个Imageview 上它都不会被拉伸。


 


设置 labels 的宽度为190 points 这样他们就不会挡住image view。


 


最终的效果如下图所示:




 


textLabel和 detailTextLabel 属性来设置text。因为这些属性指向的 labels 在这个cell中并不存在了。作为替代,你需要使用tags 来找到这些labels。


 


给Name label 的tag 设置为100,Game 的label 设置为101,Image View 的tag设置为102,通过Attributes inspector 可以找到。


 


PlayersViewController.m


如下:


 


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

 


把tableView:cellForRowAtIndexPath: 改成:


  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  2. "PlayerCell"]; 
  3.   
  4.     Player *player = (self.players)[indexPath.row]; 
  5.   
  6.     UILabel *nameLabel = (UILabel *)[cell viewWithTag:100]; 
  7.     nameLabel.text = player.name; 
  8.   
  9.     UILabel *gameLabel = (UILabel *)[cell viewWithTag:101]; 
  10.     gameLabel.text = player.game; 
  11.   
  12.     UIImageView *ratingImageView = (UIImageView *)[cell viewWithTag:102]; 
  13.     ratingImageView.image = [self imageForRating:player.rating]; 
  14.   
  15. return cell; 

 


下面运行app ,效果如下:




 


tableView:heightForRowAtIndexPath:


 


注意:你可能需要 hightForRowAtIndexPath,如果你不知道你的cell的具体高度,或者不同的行有不同的高度。


.


Main.storyboard,在Table View 的 Size inspector 设置Row Height 为55:




再运行app,看起来好多了。




 


顺路说一嘴,当你通过拖拽cell下沿的方式而不是直接设置值的方式去改变cell的高度,那么table view 的row 高度属性自动会变,当你第一次这么做的使用它就会好用。


 


Using a Subclass for the Cell


 


UITableViewCell:


  1. @interface PlayerCell : UITableViewCell 
  2.   
  3. @property (nonatomic, weak) IBOutlet UILabel *nameLabel; 
  4. @property (nonatomic, weak) IBOutlet UILabel *gameLabel; 
  5. @property (nonatomic, weak) IBOutlet UIImageView *ratingImageView; 
  6.   
  7. @end 

 


这个类本身并没有做什么事情,仅仅是增加了几个属性nameLabel,gameLabel以及ratingImageView ,并且是Outlets。


 


Main.storyboard,选中prototype cell,并在Identity inspector中把它的class改成 PlayerCell 。现在无论什么时候你通过 dequeueReusableCellWithIdentifier向tableview请求一个新的cell 时,它会返回 PlayerCell 实例而不是  UITableViewCell 。


 


注意:这里我们把类名跟reuse identifier 设置成一样了,PlayerCell 这只是我的习惯而已,类名跟reuse identifier 并没有什么关系,所以如果你想起不一样的,随你好了。


 


下面连接 labels 以及 imageview 的outlet,选择label的onnections inspector 中的New Referencing Outlet 拖拽到 table view cell 上,分别选中nameLabel ,gameLabel:




重点:你需要把controls 与table view cell连接起来,而不是视图控制器。当你的data source 要求那个table view 通过dequeueReusableCellWithIdentifier 要一个新的cell 的时候,table view 并不是给你一个真实的prototype cell,而是复制一份给你(或者重用之前那些cell中一个也说不定)。这就意味着在同一时间不止有一个PlayerCell  的实例。然后不同的label 拷贝视图访问一个outlet,这是自找麻烦(从另一方面,把prototype cell 的 actions连接到 视图控制器上是可行的,当你的cell 中有自定义按钮或者是其他继承于UIControls )


 


现在你已经连接好这些属性了,你只需要写点点data source代码。首先在PlayersViewController.m中引入PlayerCell 类:


  1. #import "PlayerCell.h" 

然后把cellForRowAtIndexPath 改为:


  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  2. "PlayerCell"]; 
  3.   
  4.     Player *player = (self.players)[indexPath.row]; 
  5.     cell.nameLabel.text = player.name; 
  6.     cell.gameLabel.text = player.game; 
  7.     cell.ratingImageView.image = [self imageForRating:player.rating]; 
  8.   
  9. return cell; 

dequeueReusableCellWithIdentifier  获取PlayerCell的实例,然后可以设置 它的 labels 以及 imageview。


 


运行应用,它看起来跟之前没什么不同,但是要注意到,你现在已经用的是自定义的tableviewcell 的子类了。


 


何去何从?


点击查看该教程的 ​​第二部分​​,它涵盖了segues,静态table view cells以及下载示例工程等。

标签:控制器,storyboard,iOS,视图,cell,Controller,part,tab
From: https://blog.51cto.com/u_3457306/5973145

相关文章

  • UITabBarController 标签栏控制器-IOS开发
    在UIKit中UITabbar代表了标签栏,而UITabBarController对其进行了封装,令多个不同的视图管理与切换变的更加轻松。构建一个标签栏控制器,首先要为每个按钮准备一个单独的页......
  • sqlite 实例教程 IOS下用sqlite打造词典-IOS开发
    sqlite是个好东西,对于移动平台来说。一直想写有关sqlite的教程,但是不知道从何写起,考虑了很久,还是从一个小Demo谈起吧。我写了一个精简版的词典,实现了增删查改的基本功能。......
  • iOS中登錄功能的體驗探究
    登錄功能是我在​​湖畔​​做的第一個需求。 當時PD给我的草圖和下圖類似:(圖片來自知乎iOS客戶端登錄界面) 不過需求中要求用戶名或者密碼錯誤時,輸入框要抖動(類似Mac登錄密......
  • IOS 6 自动布局 入门-1
    这篇文章还可以在这里找到 ​​英语​​​, ​​韩语​​​, ​​土耳其语​​​​​​来自Ray:恭喜各位!你们已经通过宣传​​iosfeast​​提前解锁了第一个有关IOS6的教......
  • iOS学习笔记45—本地通知UILocalNotification
    在iOS中有两类信息提示推送方式,一类是远程服务器推送(APNS),之前有笔记9​​,还有一类就是本地通知UILocalNotification,今天就简要的记录一下UILocalNotification的使用,代码里见......
  • iOS6下自定义UI控件外观效果
    尽管iOS原生的UI控件就已经有很不错的显示效果,但是App开发者仍然希望自己的产品与众不同,所以自定义UI外观成了每个App产品开发必做之事。今天就来做一个在iOS6下实现自定义U......
  • IOS中Json解析的四种方法
    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式。有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验(​​......
  • iOS多线程编程之NSThread的使用
    1、简介:1.1iOS有三种多线程编程的技术,分别是:1.、​​NSThread​​ 2、​​CocoaNSOperation​​ (​​iOS多线程编程之NSOperation和NSOperationQueue的使用​​)3、​​G......
  • iOS第三方开源库的吐槽和备忘
    做iOS开发总会接触到一些第三方库,这里整理一下,做一些吐槽。 目前比较活跃的社区仍旧是Github,除此以外也有一些不错的库散落在GoogleCode、SourceForg......
  • iOS 开发者必不可少的 75 个工具
    如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务。软件开发同样如此。你可以从软件开发者如何使用工具中看出他水准如何。有经验的开发者精......