首页 > 代码库 > 代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧
代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧
近期接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问。就是应该怎样制作UI界面。iOS应用是非常重视用户体验的,能够说绝大多数的应用成功与否与交互设计以及UI是否美丽易用有着非常大的关系。
而随着iOS开发发展至今。能够说在UI制作上大家逐渐分化为了三种主要流派:使用代码手写UI及布局;使用单个xib文件组织viewController或者view;使用StoryBoard来通过单个或非常少的几个(关于这点稍后会进行展开)文件构建所有UI。
应该使用哪种方式来制作UI已经是iOS开发中亘古不变的争论话题了。也许永远不会有一个统一的结论。
可是首先须要知道的是三种方式各有优劣,所以也各有自己最适用的场合。而不会有全然的孰优孰劣。
对于初学iOS开发来说。一时间事实上是非常难判定最适合自己的UI架构方式的。在这篇文章里我希望能够通过自己的经验给出一些意见,以期能帮助入门者来挑选最适合自己应用场景的方案。对于老鸟的话,也最好还是对比自己平日的使用习惯和运用场景,看看有没有能够改进或变化的地方。最后。由于我本人如今最习惯和喜欢的是用Interface Builder(之后简称IB)及xib来做UI,所以文末附上了一些IB使用时候的小技巧,算是做个总结。
代码手写UI
这样的方法常常被学院派的极客或者依赖多人合作的大型项目大规模使用。Geek们喜欢用代码构建UI,是由于代码是键盘敲出来的,这样能够做到不开IB,手不离开键盘就完毕工作,能够专注于编码环境。看起来非常cool非常高效,并且不到执行时大家都不知道会是什么样子。也显出了程序猿这一职业的高大上及神奇气息(这个真的不是在黑..想想大家一起在设计师背后指点江山的场景吧)。
大型多人合作项目使用代码构建UI,主要是看中纯代码在版本号管理时的优势,检查追踪修改以及进行代码合并相对easy一些。
另外,代码UI能够说具有最好的代码重用性。
假设你的目的是写一些能够高度重用的控件提供给其它开发人员使用,那毫无疑问最好的选择应该是使用代码来完毕UIView的子类。这样进一步的改动和其它开发人员在使用时,都会方便不少。使用代码也是最为强大的。会有xib或者StoryBoard做不了的事情,可是使用代码终于一定能够完毕所要的需求。
可是代码手写UI的劣势同一时候也是最明显的,主要就是一个字:慢。首先相比可视化的IB来说。完毕一个并不太复杂的界面。你可能须要写上数百行的UI代码。
不论是初始化一个Label,还是设定一个frame或者加入一个target-action,都须要写代码,这不仅在前期极为浪费时间,在之后维护时代码定位和寻找也会非常痛苦。其次。由于你无法直观地看到你能得到的结果。所以你非常可能须要不断地Cmd+R
/Cmd+.
来改动各个视图的位置大小。
即使你用上了Reveal或者RestartLessOften之类的工具,也还是无法特别方便地完毕须要的布局。另外加上假设须要利用AutoLayout来进行尺寸适配的话。使用代码进行约束就更加头疼了。非常多时候一个无法满足的约束的问题就够来回执行改动调试非常长时间了。
Xibs
相对于代码。使用IB和xib文件来组织UI。能够省下大量代码和时间,从而得到更快的开发速度。假设你以前受到过微软家Visual Basic或者其它Visual系的可视化界面的荼毒与残害,因此怀疑Interface Builder的纯正血统和工作能力,建议能够看看这些资料以纠正三观:Jean-Marie Hullot的Interface Builder神话以及西装革履的青涩乔帮主在NeXT时亲手用IB构建应用(须要FQ)。另外,最好还是打开你的Mac上的Application目录中或者iPhone上Apple家的各种应用。你会惊奇地发现,IB远比你看到的要强大:小至计算器取色器这类小工具。大至iWork三件套,Aperture或Final Cut这种专业级应用。无一不是使用IB来完毕UI制作的。
事实上IB和xib是从iOS SDK初次面世開始就是捆绑在开发人员工具套装内的内容了,而到了Xcode 4之后更被直接集成到了Xcode中成为了IDE的一部分。xib设计的一大目的事实上是为了良好的MVC:一般来说。单个的xib文件相应一个ViewController,而对于一些自己定义的view,往往也会使用单个xib并从main bundle进行载入的方式来载入。
IB帮助完毕view的创建,布局和与file owner的关系映射等一些列工作。对于刚開始学习的人来说,牢记xib的文件都是view的内容,有助于建立起较好的MVC的概念。从而在开发中避免或少走弯路。
xib文件之前一大被诟病的问题是文件内容过于复杂,可读性非常差。即使仅仅是简单打开没有编辑也有可能造成变化而导致合并和提交的苦难。在Xcode 5中Apple大幅简化了xib文件的格式。使其变得易读易维护。能够说如今对于xib文件在版本号管理上事实上和纯代码已经没有太大差异。仅仅要细致看过一遍xib的文件内容,自然能理解绝大部分,并不是常好地追踪并查找过往的改动记录了。
当然xib也不是完美的。最大的问题在于xib中的设置往往并不是终于设置,在代码中你将有机会覆盖你在xib文件里进行的UI设计。
在不同的地方对同一个属性进行设置。这在之后的维护中将会是噩梦般的存在。
由于事实上IB还是有所局限的,它没有逻辑推断,也非常难在执行时进行配置,而反之使用代码确是无所不能的。在使用xib时,辅以部分代码来补充和完毕功能差点儿是不可避免的。
关于这点在开发时应该予以高度重视,假设选择xib,那么要尽量将xib的工作和代码的工作隔离开来:可以使用xib完毕的内容就统一使用xib来做。而不要说三个Label当中两个在xib设置了字体而还有一个却在代码中完毕。
尽量仅保持必要的、较少的IBOutlet和IBAction会是一个好方法。
StoryBoard
iOS5之后Apple提供了一种全新的方式来制作UI,那就是StoryBoard。简单理解来说,能够把StoryBoard看做是一组viewController相应的xib,以及它们之间的转换方式的集合。
在StoryBoard中不仅能够看到每一个ViewController的布局样式。也能够明白地知道各个ViewController之间的转换关系。相对于单个的xib。其代码需求更少。也因为集合了各个xib。使得对于界面的理解和改动的速度也得到了更大提升。
降低代码量就是降低bug量,这也是程序开发中的真理之中的一个。
在Xcode5之后。StoryBoard已经成为新建项目的默认配置,这也代表了Apple对开发人员的建议和未来的方向。WWDC2013的各个Sample Code中也基本都使用了StoryBoard来进行演示。能够预见到,之后Apple必然会在这方面进行继续强化,而反之纯代码或者单个xib的方式非常可能不会再得到增强。
假设不考虑iOS版本号的支持(事实上说实话如今已经非常少还见到要从iOS4開始支持的app了吧)。如今StoryBoard面临的最大问题就是多人协作。
由于全部的UI都定义在一个文件里,因此非常多开发人员个人或企业的技术负责人觉得StoryBoard是无法进行协作开发的。事实上这很多其它的是一种对StoryBoard的陌生所造成的误解。尽管Apple并没有在WWDC明白提及,可是没有人规定整个项目仅仅能有一个StoryBoard文件。一种可行的做法是将项目的不同部分分解成若干个StoryBoard,并安排开发人员对自己的部分进行负责。简单举例比方一个有4个tab功能相互独立的基于UITabBarViewController的应用,全然能够使用4个StoryBoard来分别代表4个tab,并在相互无干扰的情况下完毕开发。这样一来就不会存在所谓的冲突问题了。StoryBoard的API是如此简单,如今的SDK中一共方法数量一仅仅手就能数过来,所以详细方法在这里就不再罗嗦了。
StoryBoard的另外的挑战来源于ViewController的重用和自己定义的view的处理。对于前者,在正确封装接口以及良好设计的基础上,事实上StoryBoard的VC重用与代码的VC重用是没有本质差别的,在StoryBoard中加入封装良好须要重用的Scene就可以解决。
而对于后者,由于StoryBoard中已经不同意有单个view的存在,因此非常多时候我们还是须要借助于单个的xib来自己定义UI。
这一点能够说是由于StoryBoard的设计思路所造成的。StoryBoard更强调的是一种层次结构,是在全局的视角上来组织UI设计和迁移。而对于单个的view,很多其它的会注重于重用和定制,而与整个项目的流程没有太大关系。相信抓住这一要点,就能非常好地了解什么时候使用xib,什么时候使用StoryBoard。
关于StoryBoard最后要说的是,如今会有一些对于StoryBoard性能上的担忧。由于相对于单个xib来说,StoryBoard文件往往更大。载入速度也对应变慢。可是事实上随着如今设备的更新换代,在iPhone4都难觅的今天,这点性能上的差距差点儿能够忽略了。而再之后的设备。不论读取还是解析,仅仅会越来越快。所以性能上的问题全然是没有操心的必要的。
我的观点和选择
我入门的时候是使用xib的。由于那时候还没有StoryBoard。而我也不是喜欢代码的学院派Geek。到如今,三种方式我都有尝试过,并分别得到了一些可能还并非特别深刻体会。对于如今的我来说。xib是我的奶酪。也是我在自己的一些项目里一直使用的方式。我能够在极短短时间内用xib架起一套包含自己定义要素和良好部件重用性复杂UI。可是在我尝试了几次使用StoryBoard制作demo之后,我已经决定在之后的项目转向使用StoryBoard。一方面由于确实是未来方向(每次新project删StoryBoard非常讨厌..),如今的StoryBoard专有的preview功能,以及之后AutoLayout的进一步改进等都非常值得期待;还有一方面也认为奶酪放一个地方太久了会不好。趁着iOS7的大变革。也更新一下自己的观念和方式,把奶酪换个地方摆摆,或许会对以后大有裨益。
对于初心者来说,我并不建议上手就直接使用代码来进行UI制作和布局,由于冗长的UI代码确实很乏味无趣。尽快看到成品,至少尽快看到原型,是保持兴趣,继续深入和从事职业的有效动力。所以假设有可能有条件。在老鸟的指导下选择StoryBoard来进行高速构建(或者假设是单个人开发的话,能够不用考虑多个StoryBoard协作。就更easy),会是入门的好选择。
而最新的教程和文档已经開始逐渐偏向StoryBoard,关于StoryBoard的问题在SO上关注度也会更高,这样在入门时会有很多其它的资料能够进行參考。
这并非说不须要关心代码UI或者xib。由于使用StoryBoard的时候在仅仅能使用代码以及自己定义单个view时。还是不可避免地须要接触它们的。这里想给的一点建议就是,尽管你不依赖代码来进行UI制作。可是了解并掌握怎样使用纯代码来从头构建UI还是非常必要的:包含从新建Window開始,到初始化ViewController。加入必要的view,设定它们的property,以及加入和处理它们的各种响应及responser链等内容。
如今iOS开发入门非常easy,Xcode和xib/StoryBoard帮助开发人员隐藏了太多的细节。可是非常多时候假设你不明确underhood究竟是些什么,为什么这些xib/StoryBoard会这样运作的话。常常会出现卡在一些非常可笑的和0基础的bug上找不着北,这事实上会是对时间的巨大浪费。非常不值得。
一些IB小技巧
最后分享一些IB使用上的小技巧作为结束吧。
当中非常多方法也能够用在StoryBoard上,所以在向我自己之前xib使用者生涯致敬的同一时候,也算是一点小的备忘总结吧。
同一时候加入多个outlet
在IB中,选中一个view并右键点击,将会出现灰色的HUD。能够在其上方便地拖拉或设定事件和outlet。你能够同一时候打开多个这种面板来一次性加入全部outlet。右键点击面板。随便拖动一以下板,然后再打开还有一个。
你会发现前一个面板也留下来了,这样你就能够方便地进行拖拽设定了。
当然。对于成组和行为类似的IBOutlet。应该直接使用IBOutletCollection来进行处理会更方便。
可视化坐标距离
IB最烦人的问题就是对其。
用代码的时候我们能够明白地指定x,y坐标。可是换到IB的时候我们很多其它的时候是靠拖拽UIView来布局。
比方须要三个间隔同样的label,除了用强大的肉眼来估測距离是否相等以外,难道仅仅能乖乖分别选中三个label,记下它们的坐标然后打开计算器来做加减法么?
显然不要那么笨,试试看选中一个label。然后按住option键并将鼠标移动到其它label上试试?你能够发现view之间的距离都以非常easy理解的方式显示出来了。不仅是同层次的view,被选中view与其它层次的view之间的距离关系也能够相同显示。
在一组view层次中进行选择
对于一些复杂的view层级关系,我们往往直接在IB中选择会比較困难。
比方view相互覆盖时,我们非常难甚至不能在编辑视图中选中底层的view。
这时候一般的做法是打开左側的view层级面板,一层层展开然后选择自己须要的view。
事实上我们也有更简单的方法:按住Cmd
和Shift
,然后在须要选择的view上方按右键。就能够列出在点击位置上全部的view的列表。藉此就能够方便高速地选中想要的view了。
加入辅助线
这么高大上的技巧必须放在最后啊...在左边的层级列表中双击某个view,然后Cmd+_
或者Cmd+|
就可以在选中的view上加入一条水平或者垂直中心的辅助线。当然这个辅助线是能够任意移动的。
假设干过设计的同学肯定明确这个的意义了。在之后的对齐和设计变更的时候都有重要的參考价值。
代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧