1. StroyBorad简介
Storyboards ios5引入
Single View Application模板创建工程Simple Storyboard
使用Use Storyboards 复选框
默认生成文件MainStoryboard.storyboard
一个应用程序委托
一个视图控制器类
sence(场景)
The arrow points out which view controller is the initial view controller。
箭头指向第一个被初始化的controller
Note that when you’re zoomed out, Interface Builder won’t let you drag any objects from the object library into your views.
放大状态下,无法添加新的控件
So how does our app know that it’s supposed to load our storyboard, and how does its initial view get put into a window?
怎么加载stroyboard,怎么初始化view并放入window?这之前都是在应用程序委托中完成的。
在此设置TARGETS-》Summary中设置Main storyboard,
将会帮你完成类似于,创建一个窗口,加载stroyboard,初始化view,创建controller,并且关联。这些都在后台帮你完成了。
make your app automatically create a window, load the storyboard and its initial view, create the initial view controller specified in the storyboard,
and hook it all up.
应用程序委托中的didFinishLaunchingWithOptions方法直接返回YES,因为其他工作都在后台通过storyboard自动完成了
2. Dynamic Prototype Cells 动态Cell原型
在storyboard中,可在tableview中创建Cell原型,不像之前要用独立的xib文件定义各种不同的cell。
而后在数据源方法中,可根据不同条件,使用不用的identifier获取不同原型的Cell,即一个表中有多种类型的Cell
Dynamic Table Content, Storyboard-Style
创建类BIDTaskListController:UITableViewController
在storyboard中,拖入一个 Table View Controller实例,并关联以上类型。
Editing Prototype Cells
创建不同的cell原型,使用不同的identifier
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)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";
} //不同的行,获取到不同的Cell
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;
}
而且,在stroyboard中定义的cell原型,只要设置了identifier,就不用在代码中显示的registerClass来想tableview注册
直接dequeue就能获取到非空的cell
动态原型解决了一个很大的问题,就是在一个storyboard中,集中一次定义很多原型。
不用分开定义,注册。
3. Static Cells 静态表单元
storyboard中,支持静态表单元,即知道个数,类型等,而不需要通过数据源方法,动态的获取。
对应此类知道布局,分区数,行数的表,太方便了。
直接在storyboard中布局,设置就可以了。
某些要改变值的地方,可以通过预先关联的输出口,来动态的改变其值。
1.创建类BIDStaticCellsController:UITableViewController
2.在storyboard中,拖入一个 Table View Controller实例,并关联以上类型。
Select table view attributes inspector, Click the popup at the very top,
labeled Content, and change it from Dynamic Prototypes to Static Cells.
3.在表属性中,就内容修改为 静态表单元
4.编辑Cells类型
5.创建outlet,action等
6.此时在controller中,不使用数据源方法,
而是在viewDidLoad中,直接修改outlet的值来控制表中cell的显示。
- (void)viewDidLoad
{
[super viewDidLoad];
// Some comments you can safely ignore right now!
NSDate *now = [NSDate date];
self.dateLabel.text = [NSDateFormatter localizedStringFromDate:now
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterNoStyle];
self.timeLabel.text = [NSDateFormatter localizedStringFromDate:now
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterLongStyle];
}
4. segue
Empty Application template
Name the project Seg Nav
新建文件MainStoryboard.storyboard,并设置Target
删除应用程序委托中,创建窗口的代码,因为此时会自动创建窗口等。。
Dragging a navigation controller into a storyboard automatically gives us a table view controller to start working with.
拖动一个navigation controller到storyboard中,会自动创建一个table view。
This arrow represents the navigation controller‘s rootViewController property
第二个箭头,代表的是navigationController的 rootviewController,即初始视图
设置tableViewController的navigation item的title和back button,
注意这个back Button定义的不是当前view显示时候的back button,而是下一个view显示的back button。
创建segue
control + drag
Selection Segue 选中行
Accessory Action 点击accessory
push
modal
custom
故事板中使用segue很简单,可以在控制器与控制器之间,某个控件和控制器之间自由拖动。
对于表视图,如果是静态表单元视图,每个都可以segue
如果是动态表单元视图,每个表单元原型也可以segue,那么用此原型创建出来的cell具有此segue
准备segue之前,将会调用此方法,来为接下来的controller准备数据
- (void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender
{
UIViewController *destination = segue.destinationViewController; //下一个目标视图控制器
if ([destination respondsToSelector:@selector(setDelegate:)])
{
[destination setValue :self forKey :@"delegate"]; //KVC
}
if ([destination respondsToSelector:@selector(setSelection:)])
{
// prepare selection infoNSIndexPath *indexPath = [self.tableView indexPathForCell: sender];
id object = self.tasks[indexPath.row];
NSDictionary *selection = @{@"indexPath" : indexPath, @"object" : object};
[destination setValue: selection forKey:@"selection"]; //KVC
}
}
//初始化
NSDictionary *selection = @{@"indexPath" : indexPath, @"object" : object};
//取值
id object = selection[@"object"];
//KVC key value coding
setValue: forKey:
valueForKey:
使用KVO,类与类之间甚至都不用头文件包含,降低了耦合
注意,prepareForSegue, 只会在segue被触发的时候调用
navigation的返回,不会触发segue,此时需要在比如 viewWillDisappear中处理响应。
总结:
stroyboard用起来很简单,只要在工程设置中关联到storyboard,
则应用程序窗口的创建,controller的初始化等,都会自动执行。
在storyboard中,支持表视图单元的动态原型,支持静态表视图。
对于某些已知布局和行数量的表,使用静态表视图太方便了。
通过control+drag实现segue,控制器到控制器,控件到控制器
在控制器中,可响应prepareForSegue来为即将显示的controller做准备