第10课: Storyboards

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 info

NSIndexPath *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做准备

时间: 2024-10-12 15:56:50

第10课: Storyboards的相关文章

Spark3000门徒第10课Java开发Spark实战总结

今晚听了王家林老师的第10课Java开发Spark实战,课后作业是:用Java方式采用Maven开发Spark的WordCount并运行在集群中 先配置pom.xml <groupId>com.dt.spark</groupId> <artifactId>SparkApps</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging

高并发之Memcached实战第10课-“Memcached Get获取数据”部分代码分享2

高并发之Memcached实战第10课-"Memcached Get获取数据"部分代码分享2 一.Memcached客户端读写在同一个程序的逻辑: MemcachedClient mcc = new MemcachedClient(list); if(mcc.get("something")==null) { if(!DataFactory.Exist(somethingObject)) { DataFactory.StoreInDB(somethingObject

安卓学习第10课——listview

1.普通listview <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" androi

第10课 - 变量与函数的综合示例

第10课 - 变量与函数的综合示例 1. 实战需求 (1)自动生成 target 文件夹存放可执行文件 (2)自动生成 objs 文件夹存放编译生成的目标文件(*.o) (3)支持调试版本的编译选项 (4)考虑代码的扩展性  --> 使用变量 2. 工具原料 - $(wildcard _pattern) 获取当前工作目录中满足_pattern的文件或目录列表 - $(addprefix _prefix, _names) 给名字列表_names中的每一个名字增加前缀_prefix 3. 关键技巧

python进阶教程 中文pdf课件版(共10课)【20MB】高清下载

Python,作为一个"老练"."小清新"的开发语言,已受到广大才男俊女的喜爱.我们也从最基础的Python粉,经过时间的摧残慢慢的变成了Python老鬼.本教程由浅入深,简单易学,需要的可下载试试! 目录 第01课 Python入门 第02课 更新版-numpy第03课 更新版-pandas第05课 python 可视化实战 第06课 PythonNLTK第07课 Python社交网络分析igraph第08课 python和机器学习 第10课 Python分布式计

第10课:Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考

上一课我们讲解了Receiver启动的流程.Receiver是通过ReceiverSupervisor的start方法启动的: /** Start the supervisor */ def start() {   onStart()   startReceiver() } 首先会调用ReceiverSupervisor的onStart()方法, override protected def onStart() {   registeredBlockGenerators.foreach { _.

第10课 OpenGL 3D世界

加载3D世界,并在其中漫游: 在这一课中,你将学会如何加载3D世界,并在3D世界中漫游.这一课使用第一课的代码,当然在课程说明中我只介绍改变了代码. 这一课是由Lionel Brits (βtelgeuse)所写的.在本课中我们只对增加的代码做解释.当然只添加课程中所写的代码,程序是不会运行的.如果您有兴趣知道下面的每一行代码是如何运行的话,请下载完整的源码,并在浏览这一课的同时,对源码进行跟踪.好了现在欢迎来到名不见经传的第十课.到现在为止,您应该有能力创建一个旋转的立方体或一群星星了,对3D

【黑马程序员】第10课:JSP+EL表达式+JavaBean

<pre> day10 上节内容回顾 1.jsp的入门 *在jsp里面如何嵌入java代码 **有三种 <%!  %>  <%= %> <%  %> *jsp就是servlet,最终也会被编译成servlet,放到tomcat的work目录里面 2.el入门 *获取域对象里面的值 *${域对象的名称} 3.cookie *cookie分类 **有两种:会话级别的cookie和持久性的cookie(使用方法setMaxAge方法) *创建cookie:new

第10课 C++中的新成员

1. 动态内存分配 (1)C++通过new关键字进行动态内存申请,是以类型为单位来申请空间大小的 (2)delete关键字用于内存释放 ▲注意释放数组时要加[],否则只释放这个数组中的第1个元素. [实例分析]C++中的动态内存分配 #include <stdio.h> int main() { int* p = new int; *p = 5; *p = *p + 10; printf("p = %p\n", p); //p保存堆上开辟空间的地址 printf("