苹果每一次推出新功能可以说都是一次比较大的变革,真的很难有人能够跟上它的节奏。iOS4.3 SDK刚开始有些理解了,iOS5就发布了,iOS的新功能刚熟悉,这不iOS6又要发布了。不管怎么样,还是先学习学习iOS5吧!
在iOS5中,一个比较特别的功能是StoryBoard,它的目的是代替历史悠久的NIB/XIB(其实StoryBoard还是基于NIB/XIB的,不过开发人员已经无需直接跟NIB打交道了)。目前关于StoryBoard的文档并不多,本文只是浅尝辄止谈谈本人对StoryBoard的一些理解。
StoryBoarding机制比之NIB/XIB的的优势何在呢?个人认为,StoryBoard有以下几个优点:
- 能够减少很多跟View相关的代码;
- 能够使View和Controller进一步解耦;
- 能够优化程序的“页面流”,使程序的结构更清楚 ;
- 能够让产品经理更好的参与开发过程,督导程序的运转流程,也让程序员关注与程序的功能。
不管怎么样,我们都需要对NIB和XIB有一个基本的认识。根据NIB 和 XIB 的区别说的:
NIB 和 XIB 都是 Interface Builder 的图形界面设计文档。引用《Cocoa Programming for Mac OSX》一书的说法,Interface Builder 把窗口、菜单栏以及窗口上的各种控件的对象都“冻结”在了一个 NIB文档里面了;程序运行时,这些对象将会“苏醒”。
在终端下我们可以看到,NIB 其实是一个目录。它里面有两个也是后缀为 NIB 的文件:designable.nib 和 keyedobjects.nib。前者是一个 XML 文档,而后者则是一个二进制文件。Interface Builder 3 之后,引入了新的文档格式:XIB。它是单一的 XML 文档,也就是一个纯文本文件。纯文本文件的好处是显而易见的。嗯,就是便于源代码版本管理。现在最新版本的 Xcode 在创建项目时,已经默认使用 XIB 格式的文档了。
不论在 Interface Builder 中选择的是 NIB 还是 XIB 格式,Xcode 编译后都将得到一个供程序运行时使用的经过编译的 NIB 文件。
根据上面的解释,NIB是和视图紧密联系的,所以NIB和ViewController相关联的,所以XCode在我们在创建ViewController会提示我们是否创建相关联的XIB文件,即对应的NIB文件。总之,之所以用Interface Builder来绘制界面,是为了减少那些设置界面属性的无聊和重复的代码,让开发人员能够集中精力实现应用程序的功能,而不在界面控制上花精力。NIB文件的作用是描述用户界面以及初始化对象和界面元素对象,等价于开发者在代码中实现NIB里描述的界面和初始化的对象。
StoryBoard的出现,则是进一步简化界面的设计过程。在StoryBoard出现之前,在不同的ViewController进行跳转需要用代码实现,NIB文件是没有办法描述从一个ViewController跳转到另一个ViewController的,这里比较常用的代码方法有 -presentModalViewController:animated:
或者借用ViewController的nativgation功能,然后调用-pushViewController:animated:方法。而
这种跳转方法完全可以使用Storyboarding,具体方法是Segue。Segue就是用来定义一个ViewController到另一个ViewController的过渡。在Storyboard里,我们只需要的是,连接界面对象和Action Method那样把ViewController之间用Segue连接起来就可以了,而不再需要手写代码了。但是在自定义Segue时,你需要实现Segue,而简化的是无需编写调用的代码,StoryBoard会帮你调用的。这就是上面所说的第一个优点。
下面两个特性参考博文浅谈iOS 5的StoryBoard
要用好Storyboarding机制,那么必须严格遵守MVC原则。要让View和Controller充分解耦;并且不同的Controller之间也要充分解耦。否则,程序的业务逻辑就会乱成一团,很难理解,维护和除虫(Debug)。
举个例子来说:在过去,特别是初学Cocoa Touch开发的时候,很多人都喜欢直接把AppDelegate
当ViewController用,直接在AppDelegate
和MainMenu.xib之间交互。应该说,这是一个非常不好的习惯。AppDelegate
的作用很简单,就是处理UIApplication的回调,而不应该负责用户界面的处理。很多iOS教程为了省事,都直接把AppDelegate当ViewController用,甚至直接举例在UIWindow上绘制界面。虽然,作为教程这么做很简单明了,因为UIWindow也是UIView的子类,但是这却不是一种优良的实践。因为由ViewController来负责处理View才是正确的做法。
近一段时间,苹果的项目模版经常发生改变,特别是自从Xcode 4发布之后,程序模版(如,View Based Application)开始鼓励使用UIWindow的rootViewController
属性来指定第一屏的ViewController,以保证AppDelegate
专注于它应该做的事情。而引入StoryBoard之后,AppDelegate
已经不管ViewController的事情了 ;第一屏所使用的ViewController(也就是rootViewController
)可以在StoryBoard中设置。这样,程序的入口点就能从StoryBoard的“设计图”上一目了然了。这是第二个优点。
至于第三个优点,就是StoryBoard的“设计图”了。StoryBoard能够包含一个程序所有的ViewController以及它们之间的连接。因此,StoryBoard甚至可以作为程序的“设计图”来用了。理想情况下,在程序开发接近尾声的时候,我们只需对比StoryBoard的“流程”和最初程序的设计“流程”,就知道程序有没有“走样”了。
最后一点,有了StoryBoard,程序员在pm定义好了程序跳转流程之后,可以肆无忌惮的开始实现程序的功能了,少了产品经理的絮絮叨叨,程序员的工作异常轻松!
虽然StoryBoard优点带来了不少的进步,但是从NIB/XIB迁移到StoryBoard还是比较麻烦的,在观念和实践上的改变难度比较大。下面简要归纳一下:
- 在做程序开发的时候,ViewController不需要NIB/XIB了(虽然在后台还是用的NIB),那么以前在NIB/XIB上做的连接Outlet和Action的操作需要在StoryBoard上完成了,以为着你需要重新连线;
- 开发过程中需要注意StoryBoard像是Controller对象的容器,而不是View对象的容器,NIB/XIB可以作为View对象的容器。因此独立于ViewController的View不能出现在StoryBoard里的,View只能通过ViewController来管理;
- UIWindow对象的作用被进一步淡化,甚至可以这么说:其实很多程序根本无需用到UIWindow对象。AppDelegate也不再被鼓励(也不能)用来做ViewController--你甚至无法在Interface Builder的StoryBoard图上找到AppDelegate对象--因为它本来就不应该用来处理界面(View)的。
- 设计模式要求越来越高。你必须严格遵守MVC设计模式,鼓励代码接耦,这样不仅能够使得代码维护容易,也让你用好StoryBoard以及帮助你理解StoryBoard的原理。
最后的最后,iOS每次发布都会引起不适应,但是人们适应之后发现这些玩意确实不错。所以放心的尝试吧!