从零开始学ios开发(十七):Storyboards(上)

在开始这章以前,先作个说明,从这篇开始,我所使用的xcode更新成了最新的版本,版本是4.6.1(4H512),以下:
web

你们能够打开本身电脑上的App Store,而后搜索xcode,第一个出现的就是Xcode,而后直接点击安装就行,很方便且智能,若是你的电脑上有旧版本的xcode,它还会提示你删除,反正整个过程我按住下来仍是很容易的。
xcode

另外,从这篇开始,我使用的教程也作了相应的升级,如今使用的教程为

这个你们去搜一下就能够找到,很方便。app

好了,其余的没什么不一样,下面开始咱们这一篇的学习。iphone

1)Storyboard简介
此次学习的内容是在iOS 5的时候才加入的一个新的东西:Storyboard,简单的翻译成“故事版”(好吧,我以为这个名字蛮挫的),它简化了一些开发app时的一些步骤,例如自动为咱们添加必要的delegate/dataSource,在多个view之间的切换,使用图和线链接各个view,让咱们可以清晰的看到各个view之间的先后关系。这样的好处是减轻了咱们在管理view以前切换时的工做量,可以让咱们把更多的注意力集中在具体的功能实现上,而后是咱们对整个的app view之间的关系有一个总体的了解。ide

Storyboard仍是基于xib(Xcode's Interface Builder),可是一个Storyboard中又能够包含多个xib,每一个xib都一个它本身的controller绑定。好像,下面先举一个简单的例子,来直观的感觉一下什么是Storyboard。布局

2)Create a Simple Storyboard
建立一个project,左边选择Application,右边选择Single View Application,点击Next
学习

将项目命名为“Simple Storyboard”,而后选中Use Storyboards,单击Next
字体

找个地方保存新建的项目,完成建立
ui

在project navigator中,默认帮咱们建立的文件有不少都是和以前同样的,有BIDAppDelegate,BIDViewController,可是咱们没有发现xib文件,取而代之的是一个MainStoryboard.storyboard,在这个storyboard中,藏着一个系统默认帮咱们建立的xib,选中MainStoryboard.storyboard,在editor area中,会出现一个xib,而整个xib的controller文件正是BIDViewController,至此全部默认建立的文件都已经对上号了。
this

打开dock,选中View Controller节点并展开,你会发现,在layout area下的一个黑色区域中显示的图标和dock中是同样的,这个黑色区域和上方的view组成了一个场景,叫作scene。(在scene中还有一个Exit,这个就不做介绍了,由于书本里面也是省略的)在view的左边有一个大大的箭头,这个箭头是用来讲明该app的起始view是哪一个。

在layout area的右下方有一个小图标,这个是用来切换iphone4和iphone5的(咱们的这个例子仍是基于iphone4的界面)
 

好了,简单的介绍就到这里,下面继续咱们这个例子,从Object library中拖一个Label放到view的中间,双击Label,输入“Simple”

好了编译运行你的程序,一个最简单的Storyboard app完成了

当咱们使用Storyboard开发app的时候,不少事情程序都会帮咱们完成,包括如何载入默认的xib。若是你选中project navigator中的项目名称

在editing pane中你能够找到程序默认载入的storyboard,这里例子中默认的storyboard是MainStoryboard.storyboard

3)Storyboard with UITableViewController
在以前几篇的例子中,咱们已经不少次的使用到了UITableViewController,对其操做的方式应该已经很熟悉了,通常是tableview中包含不少个cell,每一个cell有一个identifier,建立cell的时候用到的方法是cellForRowAtIndexPath。在storyboard中,仍是会用到这些,可是会相对简单一些,下面咱们接着上面的例子作下去。

选中Project navigator中的Simple Storyboard文件夹,单击鼠标右键,选择“New File...”,在弹出的窗口中,左边选择Cocoa Touch,右边选择Objective-C class,点击Next按钮,在下一个窗口中将class命名为BIDTaskListController,Subclass of命名为UITableViewController,点击Next按钮,完成建立。

接着选中MainStoryboard.storyboard,从Object library中拖一个Table View Controller到layout area

在dock中,选中刚才拖入的Table View Controller(这样可以抱着咱们选中的是layout area中整个的Table View Controller)

打开Identity inspector,将Class设置为BIDTaskListController,当设置完成后,dock中的table view会变成Task List Controller

这样咱们新加的TableViewController就和它的类对应起来了,tableview也知道它能够去哪里取得它所须要的数据。

在拖入的Table View Controller上,有一个默认的cell(Prototype Cells),咱们能够为其添加identifier,在其上面定制本身的cell样式(注意,咱们能够添加任意多个Prototype Cells,每一个cell用identifier来区分,定制不一样的样式,这里的cell只是一个原型,根据原型cell生成正式的cell,以后会有一个这样的例子)。咱们选中整个默认的cell,并打开attributes inspector,找到Identifier,输入plainCell

而后从object library中,拖一个Label放到原型cell上,Label如何布局看我的爱好,选中Label,在attributes inspector中找到Tag,将其值设为1,这样在code中就能够经过Tag的值找到Label了。


接着,咱们选中整个的cell,你也能够到dock中去选,这样比较准确,而后按Command + D,或者从菜单栏中选择Edit>Duplicate,复制一个cell,这样在table view中就有2个prototype cell了

(这里有一个很是有用的小技巧,当你想直接在view中选择本身想要的元素时,可是又碍于一个view上叠加的元素太多很难直接选中,那么在这时,你同时按住键盘上的shift和control键,而后在你想选择的元素上点击鼠标,会弹出一个窗口,上面罗列了鼠标点击的位置下全部存在的元素,而后你再去进行选择会变的异常的简单。
例如我在cell中的Label上点鼠标

鼠标点击的位置一共有4个层叠元素

若是咱们在cell上点击鼠标

Label不见了,只有三个元素。

这么样,用这样的方法去选择元素很简单吧,仍是蛮佩服苹果在细节方面的考虑和设计的。)

选中新加的cell,在attributes inspector中将Identifier赋值为attentionCell

选中Label,在attributes inspector中将其颜色设置为红色

好了,对于这个table view的操做所有完成,在开始具体的编写代码以前,还有一件事情,将layout area中的那个大大的箭头移到这个table view上,这样程序在载入的时候默认的会显示这个view

保存一下MainStoryboard.storyboard,下面开始具体的编码。

打开BIDTaskListController.m文件,你会发现不少经常使用的方法已经存在:
viewDidLoad
didReceiveMemoryWarning
numberOfSectionsInTableView
numberOfRowsInSection
cellForRowAtIndexPath
didSelectRowAtIndexPath
咱们只要直接往这些方法中填代码就能够了,添加以下代码

复制代码
#import "BIDTaskListController.h" @interface BIDTaskListController () @property (strong, nonatomic) NSArray *tasks; @end @implementation BIDTaskListController ...... - (void)viewDidLoad { [super viewDidLoad]; // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem;  self.tasks = @[@"Walk the dog", @"URGENT: Buy milk", @"Clean hidden lair", @"Invent miniature dolphins", @"Find new henchmen", @"Get revenge on do-gooder heroes", @"URGENT: Fold laundry", @"Hold entire world hostage", @"Manicure"]; } ...... #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation. // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return [self.tasks count]; }
复制代码

首先和以前同样,定义一个NSArray类型的tasks,用于保存table view中的行,而后在viewDidLoad中对tasks进行赋值(这里的语法和以前我看到的赋值方法有点不一样,越到后面,语句写的越是精炼啊),在numberOfSectionsInTableView中,返回1,表示只有一个section,在numberOfRowsInSection中返回section中row的数量。这些都很简单,接着添加代码

复制代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; NSString *identifier = nil; NSString *task = [self.tasks objectAtIndex:indexPath.row]; NSRange urgentRange = [task rangeOfString:@"URGENT"]; if (urgentRange.location == NSNotFound) { identifier = @"plainCell"; } else { identifier = @"attentionCell"; } UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; // Configure the cell...  UILabel *cellLabel = (UILabel *)[cell viewWithTag:1]; NSMutableAttributedString *richTask = [[NSMutableAttributedString alloc] initWithString:task]; NSDictionary *urgentAttributes = @{NSFontAttributeName : [UIFont fontWithName:@"Courier" size:24], NSStrokeWidthAttributeName : @3.0}; [richTask setAttributes:urgentAttributes range:urgentRange]; cellLabel.attributedText = richTask; return cell; }
复制代码

代码一开始定义了一个identifier,而后根据indexPath得到tasks中的task,NSRange能够认为是一个范围或者一种排列,它根据这个范围或者排列到另外一个对象去寻找,若是找到了就返回开始的位置,若是没有找到就返回NSNotFound。NSRange的对象urgentRange定义了一个字段“URGENT”,它在task中进行匹配,若是存在,那么这个cell就把plainCell赋给identifier,若是不存在则将attentionCell赋给identifier。而后根据identifier从tableView的方法dequeueReusableCellWithIdentifier中获得相应的cell。

以后的一段是对cell上的label进行操做,还记得刚才咱们在attributes inspector中将Label的Tag设置为1了吗?这里就用到了,使用viewWithTag的方法在cell中找到Label,而后对Label进行赋值,以后的一些操做是对特定的字符串“URGENT”进行操做,更改它的字体属性。这些就一笔带过吧,毕竟咱们的注意力不是集中在这个上面,对Label操做完后,将其赋给cellLabel,最后返回cell。

好了,编译运行(编译时会有warning产生,这个不用去理会,编译仍是会成功,这些warning是告诉你在Storyboard中有xib是没有被使用的,咱们的箭头没有指向它且和当前的view又没有联系,因此不会对其进行操做,有warning是正常的),效果以下

若是task中包含字符串“URGENT”那么将会使用identifier为attentionCell的cell,不然就使用identifier为plainCell的cell。

4)Static Cells
在大部分的状况下,table view中的cell都是须要动态生成了,app运行时,根据source的不一样生成不一样数量或者样式的cell,可是在某些状况下,咱们能够事先知道将要生成的cell是什么样子的,且它是固定不变的,咱们把这样的cell称之为Static Cells,与其对应的则是dynamic cell。在这里咱们举一个简单的例子来讲明这种状况。

咱们不用建立一个新的project,直接在上面的程序中接着添加代码。选中Project navigator中的Simple Storyboard文件夹,单击鼠标右键,选择“New File...”,在弹出的窗口中,左边选择Cocoa Touch,右边选择Objective-C class,点击Next按钮,在下一个窗口中将class命名为BIDStaticCellsController,Subclass of命名为UITableViewController,点击Next按钮,完成建立。

选中MainStoryboard.storyboard,再从Object library中拖一个Table View Controller到layout area,就放在原有2个view的右边,接着将箭头指向这个新添加的view

图中最右边的是新添加的view,这些view看上去比较小,是由于我了layout area右下角的,这样能够方便观察每个view(固然在缩小的状态下,是没有办法对view进行操做的,只能移动其位置,要操做view,必须将view放大回正常的大小)

选中刚才添加的controller中的table view,打开attributes inspector,找到Content,在其下拉框中选择“Static Cells”,找到Style,在其下拉框中选择“Grouped”

table view的样式也随之发生了变化,出现了3行row,section的样式变成了一个圆角矩形

选中section,在其attributes inspector设置以下,Rows改成2,Header中填写“Silliest Clock Ever”

 

改完后的section

下面对2个cell进行设置,选中第一个cell,在attributes inspector中将其Style设置为“Left Detail”

而后双击Title,改为“The Date”,重复上面的步骤,将第二个cell的Title改为“The Time”,改完后的效果

以后,咱们将建立两个outlet对象,分别指向2个Detail,这样在app运行后,就能够改变它们的值了。

如今先关联这个table view controller和它的类,在dock中选中Table View Controller,而后打开identity inspector,在Class中输入“BDIStaticCellsController”,dock中的名字也随之发生改变

仍是在dock中选中controller的状态下,将Editor的模式设置成Assistant editor,这样BIDStaticCellsController.h文件会打开(若是打开的不是这个文件,那么就手动打开吧),选中第一个cell中的Detail,而后control-drag到BIDStaticCellsController.h中并释放,会弹出个窗口,将Name命名为“dateLabel”

对第二个cell中的Detail进行相同的操做,将Name命名为“timeLabel”,添加完成后的BIDStaticCellsController.h

复制代码
#import <UIKit/UIKit.h>

@interface BIDStaticCellsController : UITableViewController
@property (weak, nonatomic) IBOutlet UILabel *dateLabel; @property (weak, nonatomic) IBOutlet UILabel *timeLabel; @end
复制代码

下面开始编写代码,打开BIDStaticCellsController.m,先将下面三个方法删除

复制代码
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation. // Return the number of sections. return 0; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Configure the cell... return cell; }
复制代码

由于咱们使用的是static cell,所以table view中section的数量,section中cell的数量都是固定不变的,咱们也不须要重新建立cell,cell一共才2个,会一直显示在屏幕上。

接着添加下面的代码

复制代码
- (void)viewDidLoad { [super viewDidLoad]; // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem;  NSDate *now = [NSDate date]; self.dateLabel.text = [NSDateFormatter localizedStringFromDate:now dateStyle:NSDateFormatterLongStyle timeStyle:NSDateFormatterNoStyle]; self.timeLabel.text = [NSDateFormatter localizedStringFromDate:now dateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterLongStyle]; }
复制代码

在viewDidLoad中,分别对dateLabel和timeLabel进行了设置,至于NSDate和NSDateFormatter的说明你们就去google一下吧,这里不作详细解释了。

编译运行,效果以下

相关文章
相关标签/搜索