是否有关于何时在 iOS 项目中使用故事板以及何时使用 XIB 的指南?每种方法的优缺点是什么,它们各自适合什么情况?
据我所知,当您的视图控制器被动态 UI 元素(如地图图钉)推动时,使用故事板转场并不是那么干净。
是否有关于何时在 iOS 项目中使用故事板以及何时使用 XIB 的指南?每种方法的优缺点是什么,它们各自适合什么情况?
据我所知,当您的视图控制器被动态 UI 元素(如地图图钉)推动时,使用故事板转场并不是那么干净。
2016 年 1 月 12 日更新:现在是 2016 年,我仍然更喜欢在代码中而不是在 Storyboard 中布置我的 UI。话虽如此,故事板已经走了很长一段路。我已经删除了这篇文章中在 2016 年不再适用的所有要点。
2015 年 4 月 24 日更新:有趣的是,正如Peter Steinberger 所注意到的那样,Apple 甚至没有在其最近开源的 ResearchKit 中使用 Storyboard (在“Interface Builder”副标题下)。
2014 年 6 月 10 日更新:正如预期的那样,Apple 不断改进 Storyboard 和 Xcode。适用于 iOS 7 及更低版本的某些要点不再适用于 iOS 8(现在已标记为这样)。因此,虽然 Storyboards 本质上仍然存在缺陷,但我将我的建议从不使用修改为有选择地在有意义的地方使用。
即使现在 iOS 9 已经发布,我还是建议反对在决定是否使用 Storyboard 时要谨慎。以下是我的理由:
故事板在运行时失败,而不是在编译时:您的 segue 名称有错字或在故事板中连接错误?它会在运行时爆炸。您使用了故事板中不再存在的自定义 UIViewController 子类?它会在运行时爆炸。如果您在代码中执行此类操作,您将在编译时及早发现它们。更新:我的新工具StoryboardLint主要解决了这个问题。
故事板很快就会变得混乱:随着项目的增长,您的故事板变得越来越难以导航。此外,如果多个视图控制器对多个其他视图控制器有多个 segue,您的故事板很快就会开始看起来像一碗意大利面,您会发现自己放大和缩小并到处滚动以找到您正在寻找的视图控制器并找出 segue 指向的位置。更新:这个问题主要可以通过将故事板拆分为多个故事板来解决,如Pilky的这篇文章和 Robert Brown的这篇文章中所述。
故事板使团队工作更加困难:因为您的项目通常只有一个巨大的故事板文件,所以让多个开发人员定期对一个文件进行更改可能会让人头疼:需要合并更改并解决冲突。当发生冲突时,很难说如何解决它:Xcode 生成故事板 XML 文件,它的设计并没有真正考虑到人类必须阅读的目标,更不用说编辑它了。
故事板使代码审查变得困难或几乎不可能:同行代码审查对您的团队来说是一件好事。但是,当您对情节提要进行更改时,几乎不可能与其他开发人员一起查看这些更改。你所能得到的只是一个巨大的 XML 文件的差异。破译真正改变了什么以及这些改变是否正确或者它们是否破坏了某些东西真的很难。
故事板阻碍代码重用:在我的 iOS 项目中,我通常创建一个类,其中包含我在整个应用程序中使用的所有颜色、字体、边距和插图,以使其具有一致的外观和感觉:如果必须的话,只需更改一行调整整个应用程序的任何这些值。如果您在情节提要中设置此类值,则会复制它们,并且在您想要更改它们时需要找到每一个出现的地方。您错过一个的机会很高,因为情节提要中没有搜索和替换。
故事板需要不断的上下文切换:我发现自己在代码中的工作和导航速度比在故事板中快得多。当您的应用程序使用故事板时,您会不断切换上下文:“哦,我想点击这个表格视图单元以加载不同的视图控制器。我现在必须打开故事板,找到正确的视图控制器,创建一个新的 segue到另一个视图控制器(我也必须找到),给 segue 一个名字,记住这个名字(我不能在故事板中使用常量或变量),切换回代码,希望我不要打错名字我的 prepareForSegue 方法的那个 segue。我多么希望我可以在我所在的地方输入这 3 行代码!不,这不好玩。在代码和情节提要(以及键盘和鼠标)之间切换会很快变老并减慢您的速度。
故事板很难重构:当您重构代码时,您必须确保它仍然符合您的故事板所期望的。当您在情节提要中移动内容时,您只会在运行时发现它是否仍然适用于您的代码。我觉得好像我必须让两个世界保持同步。在我的拙见中,它感觉很脆弱并且不鼓励改变。
故事板不太灵活:在代码中,您基本上可以做任何您想做的事情!使用情节提要,您仅限于在代码中可以做的事情的一个子集。尤其是当你想用动画和过渡做一些高级的事情时,你会发现自己“与故事板作斗争”以使其工作。
故事板不允许您更改特殊视图控制器的类型:您想将 a 更改UITableViewController
为 aUICollectionViewController
吗?还是变成平原UIViewController
?在情节提要中不可能。您必须删除旧视图控制器并创建一个新视图控制器并重新连接所有 segue。在代码中进行这样的更改要容易得多。
Storyboards 为您的项目增加了两个额外的负担:(1) Storyboard Editor 工具生成 Storyboard XML 和 (2) 解析 XML 并从中创建 UI 和控制器对象的运行时组件。这两个部分都可能存在您无法修复的错误。
故事板不允许您将子视图添加到UIImageView
:谁知道为什么。
Storyboards 不允许您为单个 View(-Controller)s 启用 Auto Layout:通过选中/取消选中 Storyboard 中的 Auto Layout 选项,更改将应用于 Storyboard 中的所有控制器。(感谢 Sava Mazăre 的这一点!)
Storyboard 破坏向后兼容性的风险更高:Xcode 有时会更改 Storyboard 文件格式,并且不能以任何方式保证您能够在几年甚至几个月后打开您今天创建的 Storyboard 文件。(感谢这一点的思想进步。请参阅原始评论)
故事板可以使您的代码更复杂:当您在代码中创建视图控制器时,您可以创建自定义init
方法,例如initWithCustomer:
. 这样,您可以使视图控制器的内部不可变,并确保在没有对象customer
的情况下无法创建此视图控制器。customer
这在使用 Storyboard 时是不可能的。您必须等待该prepareForSegue:sender:
方法被调用,然后您必须customer
在视图控制器上设置属性,这意味着您必须使该属性可变,并且您必须允许在没有customer
对象的情况下创建视图控制器. 以我的经验,这可能会使您的代码变得非常复杂,并使您更难以推理您的应用程序的流程。2016 年 9 月 9 日更新: Chris Dzombak就这个问题写了一篇很棒的文章。
这是麦当劳:用史蒂夫乔布斯关于微软的话来说:这是麦当劳(视频)!
这就是我为什么不喜欢使用故事板的原因。其中一些原因也适用于 XIB。在我从事的基于故事板的项目中,它们花费的时间比节省的时间多得多,而且它们使事情变得更复杂而不是更容易。
当我在代码中创建我的 UI 和应用程序流时,我可以更好地控制正在发生的事情,更容易调试,更容易及早发现错误,更容易向其他开发人员解释我的更改,并且更容易支持 iPhone 和 iPad。
但是,我确实同意在代码中布置所有 UI可能不是每个项目的万能解决方案。如果你的 iPad UI 在某些地方与你的 iPhone UI 有很大不同,那么为这些区域创建一个 XIB 可能是有意义的。
上面列出的许多问题都可以由 Apple 解决,我希望他们会这样做。
只是我的两分钱。
更新:在 Xcode 5 中,Apple 取消了创建没有 Storyboard 的项目的选项。我编写了一个小脚本,将 Xcode 4 的模板(带有 Storyboard-opt-out 选项)移植到 Xcode 5:https ://github.com/jfahrenkrug/Xcode4templates
我已经广泛使用 XIB,并使用 Storyboards 完成了两个项目。我的学习是:
我认为 Storyboard 是 UI 实现朝着正确方向迈出的一步,并希望 Apple 在未来的 iOS 版本中扩展它们。不过,他们需要解决“单个文件”问题,否则它们对大型项目没有吸引力。
如果我开始一个小尺寸的应用程序并且能够负担得起仅 iOS5 的兼容性,我会使用 Storyboards。对于所有其他情况,我坚持使用 XIB。
创建故事板是为了帮助开发人员可视化他们的应用程序和应用程序的流程。这很像拥有一堆 xib,但在一个文件中。
有一个与此类似的问题位于.xib 文件和 .storyboard 之间有什么区别?.
您还可以通过在需要时动态更改的代码创建自定义转换,就像使用 .xibs 一样。
优点:
缺点:
何时使用其中一个并没有对错之分,这只是一个偏好问题以及您想要使用的 iOS 版本。
我将仅说明您应该使用故事板的4 个简单原因,尤其是在您必须在产品所有者、产品经理、用户体验设计师等团队中工作的高效环境中。
我不会写任何缺点,因为约翰内斯已经在他的回答中列出了可能所有可行的缺点。而且它们中的大多数肯定是不可行的,尤其是在 XCode6 的重大改进中。
我认为您的问题没有正确答案,这只是个人经验和您感觉更舒服的问题。
在我看来,故事板是一件很棒的事情。确实,很难找出您的应用程序在运行时莫名其妙地崩溃的原因,但是经过一段时间和经验之后,您会意识到它总是与某个地方丢失的 IBOutlet 有关,您将能够轻松修复它。
唯一真正的问题是在版本控制下使用故事板在团队中工作,在开发的早期阶段可能会一团糟。但是在第一阶段之后,完全改变故事板的 UI 更新非常罕见,并且在大多数情况下,您最终会在 xml 的最后部分发生冲突,这些部分是 segue 引用,通常在您重新打开故事板时会自动修复. 在我们的团队工作中,我们更愿意处理这个问题,而不是使用大量视图代码的重型视图控制器。
我已经阅读了很多关于自动布局的评论。使用 XCode5,它得到了真正的改进,即使是自动旋转布局也非常好。在某些情况下,您必须在代码中做一些事情,但您可以简单地输出您需要编辑的约束,然后在代码中做您需要的事情。甚至为它们制作动画。
我还认为,大多数不喜欢故事板的人并没有完全尝试理解自定义手动 segue 的强大功能,您可以在其中完全自定义(在单个文件中)从一种方式过渡到另一种方式的方式,以及(使用一些技巧)甚至通过更新它的视图内容而不是完全重新加载整个东西来重用以前加载的视图控制器。最后,您实际上可以做与代码相同的事情,但我认为您可以更好地分离故事板的关注点,但我同意在许多事情上它们缺乏功能(字体、图像作为颜色背景、ecc ... )。
我没有在我的任何应用程序中使用 StoryBoard 或 XIBs .. 而是以编程方式创建所有内容。
∆ 好处:
UIView
√ 您可以为's创建任何复杂类型的 UI 或过渡动画。
√ 支持所有 iOS 版本。无需担心 < iOS 5。
√ *您的应用程序将支持您的代码中的所有 iPhone/iPod/iPad 设备。
√ 你总是在更新,因为你知道代码总是有效的。
√ *适用于任何(新)推出的设备 - 无需更改代码。
√ 一切由你决定。在某些地方你想改变一些东西——无需查看故事板或 xib。只需在特定类别中搜索即可。
√ 最后但不是列表 - 您永远不会忘记如何以编程方式管理所有内容。这是最好的事情,因为您对控制的了解比任何人都深。
我从来没有发现不使用 SB 或 XIB 的问题,因为我对此很擅长。
* 如果你已经根据屏幕尺寸设置了 UIKit 的对象框架。
PS如果你还没有做这件事——你可能会遇到困难(或者可能会觉得无聊),但是一旦你熟悉了——这对你来说真的是一个糖果。
如果您要关心 Storyboard 性能,请观看WWDC 2015 Session 407
构建时间
当界面生成器编译故事板时,它首先做两件事,它试图最大化应用程序的性能,其次它还最小化创建的 nib 文件的数量。
如果我有一个带有视图和一堆子视图的视图控制器,界面生成器,构建时间将为视图控制器创建一个 nib 文件并为视图创建一个 nib 文件。
通过为视图控制器和视图提供单独的 nib 文件,这意味着可以按需加载视图层次结构。
运行
当您使用 UI 故事板 API 分配故事板实例时,最初您分配的内存只是 UI 故事板实例本身。
没有视图控制器还没有视图。
当您实例化您的初始视图控制器时,它将为该初始视图控制器加载 nib,但同样,在有人真正要求它之前,还没有加载任何视图层次结构。
我一直在从事一个规模合理的项目(故事板用语中超过 20 个场景),并且遇到了许多限制,并且不得不反复去文档和谷歌搜索做事。
UI 都在一个文件中。即使您创建了多个情节提要,每个情节提要中仍然有许多场景/屏幕。这是中大型团队的问题。
其次,它们不能很好地与嵌入其他容器控制器等的自定义容器控制器配合使用。我们在选项卡式应用程序中使用 MFSlideMenu,并且场景有一个表格。这对于情节提要几乎是不可能的。花了几天时间,我求助于完全控制的 XIB 方式。
IDE 不允许选择处于缩小状态的控件。因此,在大型项目中,缩小主要是为了获得高级视图,仅此而已。
我会将故事板用于具有小团队规模的小型应用程序,并将 XIB 方法用于中大型团队/项目。
如果你想在多个视图控制器中重用一些 UI,那么你应该使用 XIB