什么时候使用 Storyboard 和 XIBs

在iOS项目中什么时候使用Storyboard 和 XIBs,有什么指导方针吗?它们各自的优点和缺点是什么?它们各自适用于什么情况?

就我所知,当你的视图控制器被动态UI元素(如地图引脚)推送时,使用故事板segue并不是那么干净。

54073 次浏览

故事板的创建是为了帮助开发人员可视化他们的应用程序和应用程序的流程。这很像在一个文件中有一堆xib。

还有一个类似于.xib文件和.storyboard文件的区别是什么?的问题。

您还可以通过在需要时动态更改的代码创建自定义转换,就像使用.xib一样。

优点:

  • 您可以模拟应用程序的流程,而无需编写太多代码(如果有代码的话)。
  • 更容易看到屏幕和应用程序流程之间的转换。
  • 如果需要使用故事板,也可以使用.xib。

缺点:

  • 仅适用于iOS 5+。不与iOS4工作。
  • 如果你有一个视图密集型的应用程序,很容易变得混乱。

使用哪个版本并没有对错之分,这只是你的偏好和你想要使用哪个iOS版本的问题。

我广泛使用xib,并使用storyboard完成了两个项目。我学到的是:

  • 故事板非常适合屏幕数量较少、视图之间导航相对简单的应用程序。
  • 如果您有很多视图,并且在它们之间有很多交叉导航,那么Storyboard视图就会变得混乱,并且需要做太多的工作来保持整洁。
  • 对于有多个开发人员的大型项目,我不会使用故事板,因为你的UI只有一个文件,无法轻松地并行工作。
  • 将大型应用程序拆分为多个故事板文件可能是值得的,但我还没有尝试过。这个答案显示了如何在故事板之间进行segue。
  • 您仍然需要xib:在我的两个Storyboard项目中,我必须将xib用于自定义表单元格。

我认为故事板是朝着UI实现的正确方向迈出的一步,希望苹果能在未来的iOS版本中扩展它们。他们需要解决“单一文件”问题,否则他们将不适合大型项目。

如果我开发的是一款小型应用,且只能兼容iOS5,我会使用storyboard。对于所有其他情况,我坚持使用xib。

更新1/12/2016:这是2016年,我仍然喜欢在代码中布局我的ui,而不是在故事板中。话虽如此,故事板已经走过了很长的路。我已经从这篇文章中删除了所有在2016年不再适用的观点。

更新4/24/2015:有趣的是,苹果甚至没有在他们最近的开源ResearchKit中使用storyboard作为彼得·斯坦伯格注意到了(在“界面生成器”的小标题下)。

更新6/10/2014:正如预期的那样,苹果不断改进故事板和Xcode。一些适用于iOS 7及以下的点不再适用于iOS 8(现在被这样标记)。因此,尽管故事板本身仍有缺陷,但我将我的建议从< em >不要使用< / em >修改为选择性地在有意义的地方使用

即使现在iOS 9已经发布了,我还是会建议反对在决定是否使用故事板时谨慎使用。以下是我的理由:

  • 故事板在运行时失败,而不是在编译时失败:你在你的故事板中有一个键入的segue名或连接错误?它将在运行时爆炸。你使用一个自定义的UIViewController子类它在你的故事板中已经不存在了?它将在运行时爆炸。如果您在代码中执行这些操作,您将在编译时早期捕获它们。Update:我的新工具StoryboardLint基本解决了这个问题。

  • :随着项目的发展,你的故事板变得越来越难驾驭。同样,如果多个视图控制器有多个segue到多个其他视图控制器,你的故事板很快就开始看起来像一碗意大利面你会发现自己放大缩小,到处滚动来找到你要找的视图控制器以及segue指向哪里。Update:这个问题主要可以通过将你的故事板分割成多个故事板来解决,如这篇文章由Pilky这篇文章由Robert Brown

  • 由于您的项目通常只有一个巨大的故事板文件,让多个开发人员定期对一个文件进行更改可能会令人头痛:更改需要合并并解决冲突。当冲突发生时,很难知道如何解决它:Xcode生成了故事板XML文件,它并没有真正考虑到人类必须阅读的目标,更不用说编辑它了。

  • 故事板使代码审查变得困难或几乎不可能:在你的团队中,同行代码审查是一件很棒的事情。然而,当您对故事板进行更改时,与不同的开发人员一起审查这些更改几乎是不可能的。你只能拉出一个巨大的XML文件。破译真正发生了什么变化,以及这些变化是正确的,还是它们破坏了某些东西,这真的很难。

  • < >强情节串连板阻碍代码重用< / >强:iOS在我的项目,我通常创建一个类,其中包含所有的颜色和字体,利润率和insets,我用整个应用程序给它一个一致的外观和感觉:这是一个一行的变化如果我必须调整这些值对整个应用程序。如果你在故事板中设置这些值,你复制它们,需要找到每一个发生当你想要改变他们。你很有可能错过一个,因为在故事板中没有搜索和替换。

  • 故事板需要不断的上下文切换:我发现自己在代码中工作和浏览要比在故事板中快得多。当你的应用使用故事板时,你不断切换你的上下文:“哦,我想点击这个表格视图单元格来加载一个不同的视图控制器。我现在必须打开故事板,找到正确的视图控制器,创建一个新的segue到另一个视图控制器(我也必须找到),给segue一个名称,记住这个名称(我不能在故事板中使用常量或变量),切换回代码,希望我不会为我的prepareForSegue方法输入错误的segue名称。我多么希望我能在这里输入那3行代码啊!”不,一点都不好玩。在代码和故事板之间切换(以及在键盘和鼠标之间切换)很快就会过时,并降低您的速度。

  • :当你重构你的代码时,你必须确保它仍然符合你的故事板所期望的。当你在故事板中移动东西时,你只会在运行时发现它是否仍然适用于你的代码。对我来说,好像我必须让两个世界同步。在我看来,这让人感觉脆弱,不鼓励改变。

  • :在代码中,你基本上可以做任何你想做的事情!使用情节串连板,你只能在代码中做一部分事情。特别是当你想用动画和过渡做一些高级的事情时,你会发现自己“与故事板斗争”才能让它工作。

  • 故事板不允许你改变特殊视图控制器的类型:你想改变一个UITableViewControllerUICollectionViewController?或转换为普通的UIViewController?在故事板中是不可能的。你必须删除旧的视图控制器并创建一个新的并重新连接所有的segue。在代码中进行这样的更改要容易得多。

  • 故事板为你的项目增加了两个额外的负担:(1)故事板编辑器工具,生成故事板XML和(2)运行时组件,解析XML并从中创建UI和控制器对象。这两个部分都可能存在您无法修复的错误。

  • 故事板不允许你添加子视图到UIImageView:谁知道为什么。

  • 故事板不允许你为单个视图(-Controller)启用自动布局:通过检查/取消检查故事板中的自动布局选项,更改应用于故事板中的所有控制器。(感谢Sava mazatisre提出这一点!)

  • : Xcode有时会更改Storyboard文件格式,并不能以任何方式保证你能够在几年甚至几个月后打开你今天创建的Storyboard文件。(感谢在这一点上的思想进步。见原文评论)

  • :当你在代码中创建视图控制器时,你可以创建自定义的init方法,例如initWithCustomer:。这样,你可以使你的视图控制器内部的customer是不可变的,并确保这个视图控制器不能在没有customer对象的情况下被创建。这在使用故事板时是不可能的。你将不得不等待prepareForSegue:sender:方法被调用,然后你将不得不在你的视图控制器上设置customer属性,这意味着你必须使这个属性是可变的,你将不得不允许在没有customer对象的情况下创建视图控制器。根据我的经验,这可能会极大地复杂化你的代码,使其难以推理你的应用程序的流程。Update 9/9/16: Chris Dzombak写了一篇关于这个问题的伟大文章

  • 是麦当劳:用史蒂夫·乔布斯对微软的话来说:这是麦当劳(视频)!

以下是我不喜欢使用故事板的原因。其中一些原因也适用于xib。在我所从事的基于故事板的项目中,它们所耗费的时间远远多于所节省的时间,并且它们使事情变得更复杂而不是更简单。

当我在代码中创建UI和应用流程时,我可以更好地控制发生的事情,更容易调试,更容易在早期发现错误,更容易向其他开发人员解释我的更改,更容易支持iPhone和iPad。

然而,我确实同意在代码中布局所有的用户界面可能不是一个适合每个项目的万能解决方案。如果你的iPad UI与iPhone UI在某些地方有很大不同,那么为这些地方创建一个XIB可能是有意义的。

上面提到的很多问题都可以由苹果来解决,我希望他们会这么做。

这只是我的个人意见。

更新:在Xcode 5中,苹果取消了创建一个没有Storyboard的项目的选项。我写了一个小脚本,将Xcode 4的模板(带有storyboard - option -out选项)移植到Xcode 5: https://github.com/jfahrenkrug/Xcode4templates

我不认为你的问题有一个正确的答案,这只是个人经验和你觉得更舒服的问题。

在我看来,故事板是一个伟大的东西。确实,很难找出应用程序在运行时莫名其妙地崩溃的原因,但经过一段时间和经验后,您会意识到这总是与某个IBOutlet丢失有关,您将很容易地能够修复它。

唯一真正的问题是在版本控制下使用故事板的团队中工作,在开发的早期阶段可能会非常混乱。但在第一阶段之后,完全改变故事板的UI更新非常罕见,大多数情况下,xml的最后部分会发生冲突,这些segue引用通常会在你重新打开故事板时自动修复自己。在我们的团队工作中,我们更喜欢处理这个问题,而不是使用带有大量视图代码的笨重视图控制器。

我读过很多反对自动布局的评论。XCode5得到了很大的改进,它甚至可以很好地自动布局。在某些情况下,您必须在代码中做一些事情,但您可以简单地输出需要编辑的约束,然后在代码中做您需要做的事情。甚至是动画。

我还认为大多数不喜欢故事板的人都没有充分理解自定义手动segue的强大功能,在那里你可以完全自定义(在一个文件中)你从一种方式过渡到另一种方式,甚至(通过一些技巧)重用之前加载的视图控制器,只需更新它的视图内容,而不是完全重新加载整个东西。 最后你可以做和在代码中一样的事情,但我认为你可以更好地分离故事板的关注点,但我同意在许多方面它们缺乏特性(字体,图像作为颜色背景,ecc…)

我将陈述为什么你要使用故事板,特别是在你必须在一个由产品负责人、产品经理、UX设计师等组成的团队中工作的高效环境中。

  1. 他们鼓励你和他们一起工作。这意味着他们不会打破你现有的项目更新,他们将确保故事板是未来的新XCode/iOS版本的证明。
  2. 更明显的成果更少的时间为产品所有者和经理,即使在创建阶段。您甚至可以使用故事板本身作为屏幕流程图,并在会议中讨论它。
  3. 甚至在应用程序完成后(这通常是它的生命周期开始的地方)——将来它将是更快,更容易应用小的调整。这些可以同时改变你的布局的多个方面,你可能希望以所见即所得的方式看到。另一种选择是在代码中手写UI更改,并在IDE和模拟器之间来回切换以测试它,每次都等待编译&构建。
  4. 非开发人员也可以学习在故事板中设置布局,并为开发人员创建必要的钩子(IBOutlets和ibaction)。这是一个非常大的优点,因为它让开发人员专注于逻辑,用户体验设计师以可视化的方式应用他们的更改,而不需要编写任何代码。

我不会写任何反对意见,因为Johannes已经在他的回答中列出了可能所有可行的理由。其中大多数肯定是不可行的,特别是在XCode6的主要改进下。

我没有使用StoryBoard或xib在我的任何应用程序。而是以编程的方式创建一切。

∆受益:

你可以为UIView创建任何复杂类型的UI或过渡动画。

√支持所有iOS版本。没有必要担心<iOS 5。

√*你的应用程序将在你的代码中支持所有iPhone/iPod/iPad设备。

你总是会得到更新,因为你知道永远有效的代码。

√*将工作在任何(新)设备推出-无需更改代码。

一切由你决定。在某些地方,你想改变一些东西-不需要看故事板或xib。只要在特定的类中搜索。

√最后但不是列表-你永远不会忘记,如何以编程方式管理一切。这是最好的事情,因为你知道,控制得非常深。

我从来没有发现不使用SB或xib的问题,因为我很擅长这个。

*如果你根据屏幕大小设置UIKit的对象帧。

附注:如果你还没有做过这件事——你可能会遇到困难(或者可能会觉得无聊),但一旦你熟悉了它——它真的是你的糖果。

如果你关心故事板的性能,请观看2015年全球开发者大会407场

enter image description here

构建时间

当接口构建器编译故事板时,它做了两件事 首先,它试图最大化应用程序的性能 其次,它还最小化了创建的nib文件的数量 如果我有一个视图控制器,有一个视图和一堆子视图, 接口构建器,构建时将创建一个nib文件 视图控制器,并为视图创建一个nib文件 通过为视图控制器和视图控制器拥有独立的nib文件 视图,这意味着视图层次结构可以按需加载

运行时

当你使用UI storyboard, API分配一个storyboard实例时, 最初你分配的内存都是uistoryboard 实例本身。< / p >

没有视图控制器,没有视图。

当你实例化初始视图控制器时,它将加载nib 对于初始视图控制器,同样,没有视图层次结构

我一直在做一个规模合理的项目(用故事板的说法是>20个场景),遇到了许多限制,不得不反复去文档和谷歌搜索做事情。

  1. UI都在一个文件中。即使您创建了多个故事板,每个故事板中仍然有许多场景/屏幕。这在大中型团队中是一个问题。

  2. 其次,它们不能很好地与嵌入其他容器控制器的自定义容器控制器一起使用。我们在一个选项卡应用程序中使用MFSlideMenu,场景有一个表。这在故事板中几乎是不可能做到的。在花了几天时间之后,我已经采取了完全控制XIB的方式。

  3. IDE不允许选择处于缩小状态的控件。因此,在大型项目中,缩小主要是为了获得高层视图,仅此而已。

对于团队规模较小的小型应用程序,我会使用故事板;对于中型团队/项目,我会使用XIB方法。

如果你想在多个视图控制器中重用某些UI,那么你应该使用xib