StoryBoard是iOS 5的新特征,旨在代替历史悠久的NIB/XIB(其实StoryBoard还是基于NIB/XIB的,不过开发人员已经无需直接跟NIB打交道了)。目前关于StoryBoard的文档并不多,苹果的iOS 5的开发者文档里也仅有不多的介绍。所以,本文只是简单的谈谈本人对StoryBoard的一些粗浅的理解。(StoryBoard有时也叫做StoryBoarding,我不太注意这种细节,所以两个词经常会混用,如果你英语可以的话,能体会到两者的细微差别)
StoryBoarding机制比之NIB/XIB的的优势何在呢?个人认为,StoryBoard有以下几个优点:
要理解这些优点,我们先要对NIB有一个基本的认识。通常,NIB是和ViewController相关联的,很多ViewController都有对应的NIB文件。NIB文件的作用是描述用户界面以及初始化对象和界面元素对象。其实开发者在NIB里描述的界面和初始化的对象都能够在代码中实现;之所以用Interface Builder来绘制界面,是为了减少那些设置界面属性的无聊和重复的代码,让开发人员能够集中精力做程序的功能。
而StoryBoard的出现,则是进一步加强了这方面的功能;NIB文件是没有办法描述从一个ViewController到另一个ViewController的过渡的。这种过渡只能靠手写代码来实现。相信很多人都会经常用到 -presentModalViewController:animated:
以及-pushViewController:animated:
这两个方法。这种代码在Storyboarding里将成为历史;取而代之的是Segue。Segue定义了从一个ViewController到另一个ViewController的过渡。在Storyboard里,我们只需要像连接界面对象和Action Method那样把ViewController之间用Segue连接起来就可以了,不再需要手写代码了。即便你像自定义Segue,你也只需写Segue的实现,而无需编写调用的代码,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的“流程”和最初程序的设计“流程”,就知道程序有没有“走样”了。
说完了优点,我们来看看从NIB/XIB到StoryBoard的迁移,我们需要有哪些理解和实践上的改变呢?
StoryBoard是非常好的鼓励MVC和代码解耦的手段,能够让开发人员写出更加容易维护的代码。不过对于初学者来说,确实是个对理解力的小挑战。不过作为初学者也不用担心,一旦突破了理解障碍,你就会发现StoryBoard也非常好用--就像最初理解NIB/XIB时,Outlet和Action“拉线”来“拉线”去,看起来也很神奇;理解之后,发现原来“拉线”神马的也没那么神秘。
好了,絮絮叨叨的啰嗦了这么多无聊的文字,相信你也看累了。如果你依然对我写的东西不知所云的话,你可以稍稍研究一下Xcode 4.2的几个内建模版,然后和使用XIB的模版对比一下,看看苹果是怎么用StoryBoard的,能够很好的帮助你理解Storyboarding机制。当然,千万不要忘记亲自动手用一用StoryBoard!
Happy Coding!
【更新】
在看了WWDC 2011 的session video:UIViewController Containment这个视频之后,我感觉,正确的处理UIViewController
之间的层级关系对于Storyboard来说非常重要,两者能够相得益彰。而window.rootViewController
的使用,虽然也是鼓励用户不要把AppDelegate
当ViewController
用,更重要的是鼓励用户使用正确的UIViewController
层级关系。
总体上来说,Storyboard有以下好处:
我在新项目使用Storyboard时,却发现它只是看上去很美,真正用起来,却有很多问题,我发现的问题有:
我仔细比较权衡了一下优缺点,最主要的问题是我的版本管理在多人协作开发时将陷入灾难,而这是完全不能接受的。而最主要的好处就是,你可以在一个类似白板的地方“一揽众山小“一样了解所有界面之间的切换关系,但这个有那么重要吗?我自已其实很清楚跳转逻辑,这个只是对新同事了解项目代码时有帮助,那我花一点时间直接给他讲讲画画不就搞定的吗?为了这点好处而让版本管理无法使用,是完全不能接受的。
所以最终我决定放弃使用StoryBoard了,这个“看上去很美”的功能有着不可接受的缺陷。现在看来,它仅适用于做一些Demo的开发。苹果一直没有处理好这类可视化界面设计功能的版本管理,象xib文件,虽然是xml格式的,但如果多人编辑了,合并起来也会很麻烦。所以业界好多同行都不用xib,直接用纯代码来写界面,虽然稍慢一点儿,但是工程很干净,也基本没有了多人协作的版本冲突问题。