何时使用Storyboard以及何时使用XIB
有什么时候在iOS项目中使用故事板以及何时使用XIB的指导原则? 每个人的利弊是什么,他们各自适合什么情况?
附近我可以告诉它,当视图控制器被dynamicUI元素(如地图引脚)推动时,使用storyboard segues并不是那么干净。
我广泛使用了XIB,并使用Storyboard完成了两个项目。 我的学习是:
- 故事板适用于屏幕数量less到中等,视图之间相对简单的导航。
- 如果你有很多的意见和他们之间的交叉导航大量的故事板视图变得混乱和太多的工作,保持清洁。
- 对于具有多个开发人员的大型项目,我不会使用Storyboard,因为您的UI只有一个文件,并且不能轻松地并行工作。
- 大型应用程序分解成多个故事板文件可能是值得的,但我还没有尝试过。 这个答案显示了如何在故事板之间进行漫游。
- 您仍然需要XIB:在我的两个Storyboard项目中,我都必须使用XIB来定制表格单元格。
我认为故事板是UI实现的正确方向的一步,并希望苹果将在未来的iOS版本中扩展它们。 他们需要解决“单个文件”的问题,否则他们不会对大型项目有吸引力。
如果我开始一个小尺寸的应用程序,并且只能兼容iOS5,那么我会使用Storyboard。 对于所有其他情况,我坚持XIB。
更新 2016年1月12日:这是2016年,我还是喜欢在代码中而不是在故事板中布置我的用户界面。 这就是说,故事板已经走了很长的路。 我已经删除了这个post中的所有要点,而这些只是在2016年不再适用。
更新4/24/2015 :有趣的是,苹果公司甚至没有在最近开源的ResearchKit中使用Storyboard,正如Peter Steinberger已经注意到的 (在子接口“Interface Builder”下)。
更新2014年6月10日 :正如预期的,苹果不断改进故事板和Xcode。 一些适用于iOS 7及以下版本的要点不再适用于iOS 8(现在标记为这样)。 所以虽然Storyboards本身仍然存在缺陷,但我修改我的build议, 不要使用有select性地使用它的意义 。
即使现在iOS 9已经出来,我会build议 反对 决定是否使用情节串联图板时要小心。 这是我的原因:
-
故事板在运行时失败,而不是在编译时 :在segue名称中有拼写错误或在故事板中连接错误? 它会在运行时炸毁。 你使用了一个自定义的UIViewController子类,在故事板中不再存在吗? 它会在运行时炸毁。 如果你在代码中做这样的事情,你可以在编译期间尽早地捕捉到它们。 更新 :我的新工具StoryboardLint主要解决这个问题。
-
故事板快速混淆 :随着项目的增长,故事板越来越难以导航。 另外,如果多个视图控制器对多个其他视图控制器具有多个队列,那么您的情节串联板很快会开始看起来像一碗意大利面条,您会发现自己放大和缩小并滚动到所有地方,find您正在查看的视图控制器并找出哪些地方在哪里。 更新 :这个问题大部分可以通过将你的Storyboard拆分成多个Storyboard来解决,正如本文由Pilky和Robert Brown 撰写的 这篇文章所描述的。
-
故事板让团队工作变得更困难 :因为通常你的项目只有一个巨大的故事板文件,所以有多个开发者定期对这个文件进行修改会让人头痛:修改需要合并,冲突解决。 当发生冲突时,很难说清楚如何解决它:Xcode生成故事板XML文件,并没有真正devise目标,人们必须阅读,更不用说编辑了。
-
故事板使代码评论变得困难或几乎不可能 :同行代码评论对你的团队来说是一件好事。 但是,当您更改故事板时,几乎不可能使用其他开发人员来查看这些更改。 所有你可以拉起来是一个巨大的XML文件的差异。 破译真正的变化,如果这些变化是正确的,或者如果他们打破了什么是非常困难的。
-
故事板妨碍代码重用 :在我的iOS项目中,我通常会创build一个类,其中包含我在整个应用程序中使用的所有颜色,字体以及边距和插入,以使其具有一致的外观和感觉:如果必须调整整个应用程序的任何值。 如果您在故事板中设置了这些值,则需要重复这些值,并且需要查找每个发生的情况。 你错过了一个机会,因为没有search和更换故事板。
-
故事板需要不断的上下文切换 :我发现自己的工作和导航代码比故事板快得多。 当你的应用程序使用故事板时,你不断地切换你的上下文:“哦,我想要在这个表格视图单元上加载一个不同的视图控制器,我现在必须打开故事板,find正确的视图控制器,创build一个新的segue到另一个视图控制器(我也必须find),给这个segue一个名字,记住这个名字(我不能在常用的storyboard中使用常量或variables),切换回代码,并希望我不会错误的名字那为我的prepareForSegue方法继续下去,我希望我能在这里input这三行代码! 不,这不好玩。 在代码和情节串连图板(以及键盘和鼠标之间)之间切换会变得很快,并且会降低速度。
-
故事板很难重构 :当你重构你的代码时,你必须确保它仍然符合你的故事板所期望的。 当您在故事板中移动时,只会在运行时发现它是否仍然适用于您的代码。 我觉得我必须保持两个世界同步。 这种感觉很脆弱,并且阻碍了我的愚见。
-
故事板不太灵活 :在代码中,基本上可以做任何你想要的事情! 通过故事板,您仅限于代码中的一部分。 特别是当你想用animation和转换做一些先进的事情时,你会发现自己“与故事板战斗”,以使其工作。
-
故事板不让你改变特殊的视图控制器的types :你想改变一个
UITableViewController
到一个UICollectionViewController
? 或者到一个普通的UIViewController
? 在故事板中不可能。 你必须删除旧的视图控制器,并创build一个新的重新连接所有的赛格。 在代码中做这样的改变要容易得多。 -
故事板为您的项目增加了两个额外的负债 :(1)Storyboard Editor工具,用于生成故事板XML;(2)运行时组件,用于parsingXML并从中创buildUI和控制器对象。 这两个部分都可能有你无法修复的错误。
-
故事板不允许你添加一个子视图到
UIImageView
:谁知道为什么。 -
故事板不允许为单个视图(控制器)启用自动布局 :通过选中/取消选中故事板中的自动布局选项,更改将应用于故事板中的所有控制器。 (感谢SavaMazăre对这一点!)
-
故事板具有较高的破坏向后兼容性的风险 :Xcode有时会更改故事板文件格式,并不能保证以任何方式打开您今后几年甚至几个月创build的Storyboard文件。 (感谢这一点的思想见解, 请参阅原始评论 )
-
故事板可以使你的代码更复杂 :当你在代码中创build视图控制器时,你可以创build自定义的
init
方法,例如initWithCustomer:
这样,你可以让你的视图控制器内的customer
不变,并确保这个视图控制器不能创build没有customer
对象。 使用Storyboard时,这是不可能的。 你将不得不等待prepareForSegue:sender:
方法被调用,然后你将不得不在你的视图控制器上设置customer
属性,这意味着你必须使这个属性是可变的,你将不得不允许视图控制器无需customer
对象即可创build。 根据我的经验,这可能会使您的代码变得非常复杂,并且导致您的应用程序stream动变得更加困难。 更新9/9/16 :Chris Dzombak写了一篇关于这个问题的文章 。 -
这是麦当劳 :用史蒂夫·乔布斯关于微软的话来说: 麦当劳(video) !
这些是我为什么不喜欢使用故事板的原因。 其中一些原因也适用于XIB。 在我所做的基于故事板的项目上,他们花费我比保存更多的时间,他们让事情变得更加复杂而不是简单。
当我使用代码创buildUI和应用程序stream程时,我掌握了更多的内容,更容易debugging,更容易早期发现错误,更容易向其他开发人员解释我的更改,更容易支持iPhone和iPad。
但是,我确实同意在代码中布置所有的用户界面可能不是一个适用于每个项目的万能解决scheme。 如果您的iPad用户界面在某些地方与您的iPhone用户界面差别很大,则可以为这些区域创buildXIB。
上面列出的很多问题都可以由苹果公司解决,我希望他们会这样做。
只是我的两分钱。
更新 :在Xcode 5中,Apple取消了创build没有Storyboard的项目的选项。 我写了一个小脚本,将Xcode 4的模板(包含Storyboard-opt-out选项)移植到Xcode 5中: https : //github.com/jfahrenkrug/Xcode4templates
创build故事板是为了帮助开发人员可视化他们的应用程序和应用程序的stream程。 这很像有一堆xib,但在一个单一的文件。
有一个类似于这个问题的.xib文件和.storyboard有什么区别? 。
您也可以通过代码创build自定义转换,如果需要,将会dynamic更改,就像使用.xibs一样。
优点:
- 如果有任何代码,你可以模拟一个应用程序的stream程,而不需要写太多的东西。
- 更容易看到屏幕和应用程序stream之间的转换。
- 如果需要,还可以使用.xibs与故事板。
缺点:
- 只适用于iOS 5+。 不适用于iOS4。
- 如果你有一个非常密集的应用程序,可以很容易地混乱。
当使用其中一个或者另一个的时候真的没有对错,这只是一个偏好的问题,你想要使用的是什么样的iOS版本。
我只想说出为什么要使用故事板的四个简单的原因 ,特别是在需要在产品所有者,产品经理,UXdevise师等团队中工作的高效环境中。
- 苹果已经大大改善了故事板的工作。 他们鼓励你和他们一起工作。 这意味着他们不会因为更新而破坏现有的项目,他们将确保故事板能够为更新的XCode / iOS版本提供未来certificate。
- 即使在创build阶段,产品所有者和pipe理者也可以在更短的时间内获得更明显的结果 。 您甚至可以将故事板本身用作屏幕stream图,并在会议中进行讨论。
- 即使在一个应用程序完成后 (这通常是其生命周期开始的地方) – 将来应用小调整将会更快更容易 。 这些可以很好地改变你的布局的多个方面,你可能想看到一个所见即所得的方式。 另一种方法是手工编写代码中的UI更改,并在IDE和模拟器之间来回切换,以便对其进行testing,每次都要等待编译和构build。
- 可以教非开发人员在故事板中设置布局,并为开发人员创build必要的钩子(IBOutlets和IBActions)。 这是一个非常大的优势,因为它可以让开发人员专注于逻辑,用户体验devise师以可视化的方式应用他们的变化,而不必编写任何代码。
我不会写出任何缺点,因为约翰内斯已经在他的答案中列出了所有可行的答案。 而且绝大多数都是不可行的,特别是XCode6的重大改进。
我不认为你的问题有一个正确的答案,这只是个人经验的问题,你觉得更舒适。
在我看来,故事板是一个伟大的事情。 这是真的,很难找出你的应用程序在运行时神秘地崩溃了,但经过一段时间和经验,你会发现它总是与某个IBOutlet丢失,你会很容易地修复它。
唯一真正的问题是在故事板版本控制下的团队工作,在发展的早期阶段,它可能是一个真正的混乱。 但在第一阶段之后,完全改变故事板的UI更新是非常罕见的,并且在大多数情况下,最终会在xml的最后部分发生冲突,这些是通常在重新打开故事板时自动自动填充的细分引用。 在我们的团队工作中,我们首选处理这个问题,而不是使用大量查看代码的繁重的视图控制器。
我已经阅读了许多意见againts自动布局。 随着XCode5它得到了真正的改善,即使是自动旋转布局真的很好。 在某些情况下,您必须在代码中执行某些操作,但是您可以简单地输出您需要编辑的约束,然后在代码中执行所需的操作。 甚至animation他们。
我也认为,大多数不喜欢故事板的人并没有完全去理解自定义手册segue的能力,在那里你可以完全自定义(在一个文件中)你从一种方式转换到另一种方式,也可以一些技巧)甚至重用一个以前加载的视图控制器,只是更新它的视图内容,而不是完全重新加载整个事情。 最后,你可以做的代码相同的事情,但我认为你有一个更好的问题与故事板的分离,但我同意,在许多事情,他们缺乏function(字体,图像作为背景颜色,ecc … )。
我没有在我的任何应用程序中使用StoryBoard或XIB,但以编程方式创build一切。
Δ好处:
√您可以为UIView
创build任何复杂types的UI或过渡animation。
√支持所有的iOS版本。 无需担心<iOS 5。
√*您的应用程序将支持您的代码中的所有iPhone / iPod / iPad设备。
√你总是更新,因为你知道将始终工作的代码。
√*将启动任何(新)设备 – 无需更改代码。
√一切都取决于你。 在某个地方你想改变一些东西 – 不需要看故事板或xib。 只要在特定的阶层search它。
√最后但不是列表 – 你永远不会忘记,如何以编程方式pipe理一切。 这是最好的事情,因为你知道任何人都非常深的控制。
我从来没有发现没有使用SB或XIBs的问题,因为我很好。
*如果你已经根据屏幕大小设置了UIKit的对象框架。
PS如果你还没有做这件事情 – 你可能会遇到困难(或者可能会觉得无聊),但是一旦你熟悉了这一点 – 它真的是一个糖果。
如果您要关注故事板性能,请观看WWDC 2015 Session 407
build立时间
当界面构build器编译故事板时,首先要做两件事情,一是试图最大限度地提高应用程序的性能,二是最小化创build的nib文件的数量。
如果我有一个视图控制器的视图和一堆子视图,接口生成器,构build时间将创build一个视图控制器的笔尖文件,并创build一个视图的笔尖文件。
通过为视图控制器和视图分别使用nib文件,这意味着视图层次结构可以按需加载。
运行
当使用UI storyboard API分配故事板实例时,最初所有分配内存的是UI故事板实例本身。
没有视图控制器没有意见。
当你实例化你的初始视图控制器时,它将加载该初始视图控制器的笔尖,但是,再次,没有视图层次结构已经加载,直到有人真正要求它。
我一直在研究一个规模合理的项目(在故事板上的说法中有20多个场景),并且遇到了很多限制,不得不多次去文档和谷歌search做事情。
-
UI全部在一个文件中。 即使您创build了多个故事板,每个故事板仍然有很多场景/屏幕。 这在中型团队中是个问题。
-
其次,它们不能很好地与其他容器控制器等embedded的容器控制器配合使用。我们在一个选项卡式应用程序中使用MFSlideMenu,场景中有一个表格。 这是几乎不可能做一个故事板。 花了几天时间,我已经采取了完全控制XIB的方式。
-
IDE不允许在缩小状态下select控件。 所以,在一个大型项目中,缩小主要是为了获得高层次的视图,而没有什么更多。
我会为小团队规模的小型应用程序使用storyboard,并为大中型团队/项目使用XIB方法。