何时使用 Storyboard 以及何时使用 XIB
Posted
技术标签:
【中文标题】何时使用 Storyboard 以及何时使用 XIB【英文标题】:When to use Storyboard and when to use XIBs 【发布时间】:2012-03-13 08:26:50 【问题描述】:是否有关于何时在 ios 项目中使用故事板以及何时使用 XIB 的指南?各自的优缺点是什么,各自适合什么情况?
据我所知,当您的视图控制器被动态 UI 元素(如地图图钉)推动时,使用故事板转场并不是那么干净。
【问题讨论】:
如果你想让你的应用也开启 iOS4,你别无选择:在这种情况下你不能使用故事板 对 SO 进行“令人难以置信的过时”质量检查的一个很好的例子!! 【参考方案1】:2016 年 1 月 12 日更新:现在是 2016 年,我仍然更喜欢用代码而不是 Storyboard 来布置我的 UI。话虽如此,故事板已经走了很长一段路。我已经删除了这篇文章中在 2016 年不再适用的所有要点。
2015 年 4 月 24 日更新:有趣的是,Apple 甚至没有在他们最近开源的 ResearchKit 中使用 Storyboard 作为Peter Steinberger has noticed(在“Interface Builder”子标题下)。
2014 年 6 月 10 日更新:正如预期的那样,Apple 不断改进 Storyboard 和 Xcode。适用于 iOS 7 及更低版本的某些要点不再适用于 iOS 8(现在已标记为这样)。因此,虽然 Storyboard 本身仍然存在缺陷,但我将我的建议从 不要使用 修改为 在有意义的地方选择性地使用强>。
即使现在 iOS 9 已经发布,我还是建议反对在决定是否使用 Storyboard 时要谨慎。以下是我的理由:
Storyboards 在运行时失败,而不是在编译时失败:您的 segue 名称有错字或在您的 Storyboard 中连接错误?它会在运行时爆炸。您使用了故事板中不再存在的自定义 UIViewController 子类?它会在运行时爆炸。如果您在代码中执行此类操作,您将在编译时及早发现它们。 更新:我的新工具StoryboardLint主要解决了这个问题。
故事板很快就会变得混乱:随着项目的增长,您的故事板变得越来越难以导航。此外,如果多个视图控制器对多个其他视图控制器有多个 segue,您的故事板很快就会开始看起来像一碗意大利面,您会发现自己放大和缩小并到处滚动以找到您正在寻找的视图控制器并找出 segue 指向的位置。 更新:如this article by Pilky 和this article by Robert Brown 中所述,此问题主要可以通过将您的故事板拆分为多个故事板来解决。
故事板使团队工作更加困难:因为您的项目通常只有一个巨大的故事板文件,所以让多个开发人员定期更改该文件可能会让人头疼:更改需要合并并解决冲突。当发生冲突时,很难说如何解决它:Xcode 会生成故事板 XML 文件,但它的设计并不是真正考虑到人类必须阅读的目标,更不用说编辑它了。
故事板使代码审查变得困难或几乎不可能:同行代码审查对您的团队来说是一件很棒的事情。但是,当您对情节提要进行更改时,几乎不可能与其他开发人员一起查看这些更改。你所能得到的只是一个巨大的 XML 文件的差异。破译真正改变了什么以及这些改变是正确的还是破坏了某些东西真的很难。
Storyboards 阻碍代码重用:在我的 iOS 项目中,我通常会创建一个类,其中包含我在整个应用程序中使用的所有颜色、字体、边距和插图,以使其保持一致外观和感觉:如果我必须为整个应用程序调整这些值中的任何一个,这是一个单行更改。如果您在情节提要中设置此类值,则会复制它们,并且在您想要更改它们时需要找到每一个出现的地方。您错过一个的机会很高,因为情节提要中没有搜索和替换。
故事板需要不断的上下文切换:我发现自己在代码中的工作和导航速度比在故事板中快得多。当您的应用程序使用故事板时,您会不断切换上下文:“哦,我想点击这个表格视图单元以加载不同的视图控制器。我现在必须打开故事板,找到正确的视图控制器,创建一个新的 segue到另一个视图控制器(我也必须找到),给 segue 一个名字,记住这个名字(我不能在故事板中使用常量或变量),切换回代码,希望我不要打错名字我的 prepareForSegue 方法的那个 segue。我多么希望我可以在我所在的地方输入这 3 行代码!不,这不好玩。在代码和情节提要之间(以及键盘和鼠标之间)切换会很快过时并减慢您的速度。
故事板很难重构:重构代码时,您必须确保它仍然符合故事板的预期。当您在情节提要中移动内容时,您只会在运行时发现它是否仍然适用于您的代码。我觉得好像我必须让两个世界保持同步。我的拙见感觉很脆弱,不鼓励改变。
故事板不太灵活:在代码中,您基本上可以做任何您想做的事情!使用情节提要,您仅限于在代码中可以做的事情的一个子集。尤其是当您想用动画和过渡做一些高级的事情时,您会发现自己“与故事板作斗争”以使其发挥作用。
Storyboards 不允许您更改特殊视图控制器的类型:您想将UITableViewController
更改为UICollectionViewController
?还是变成普通的UIViewController
?在情节提要中不可能。您必须删除旧视图控制器并创建一个新视图控制器并重新连接所有 segue。在代码中进行这样的更改要容易得多。
Storyboards 为您的项目增加了两个额外的责任:(1) Storyboard Editor 工具,用于生成 Storyboard XML,以及 (2) 解析 XML 并创建 UI 和控制器的运行时组件从它的对象。这两个部分都可能存在您无法修复的错误。
故事板不允许您向 UIImageView
添加子视图:谁知道为什么。
Storyboards 不允许您为单个 View(-Controller)s 启用自动布局:通过选中/取消选中 Storyboard 中的 Auto Layout 选项,更改将应用于所有故事板中的控制器。 (感谢 Sava Mazăre 的这一点!)
Storyboard 破坏向后兼容性的风险较高:Xcode 有时会更改 Storyboard 文件格式,并且不保证您可以打开自己创建的 Storyboard 文件几年甚至几个月后的今天。 (感谢thoughtadvances。See the original comment)
Storyboards 可以使您的代码更复杂:当您在代码中创建视图控制器时,您可以创建自定义 init
方法,例如 initWithCustomer:
。这样,您可以使视图控制器内部的customer
不可变,并确保在没有customer
对象的情况下无法创建此视图控制器。这在使用 Storyboard 时是不可能的。您必须等待 prepareForSegue:sender:
方法被调用,然后您必须在视图控制器上设置 customer
属性,这意味着您必须使该属性可变并且您必须允许视图控制器在没有customer
对象的情况下创建。以我的经验,这可能会使您的代码变得非常复杂,并使您更难以推理您的应用程序的流程。 2016 年 9 月 9 日更新:Chris Dzombak 写了一封 great article about this problem。
这是麦当劳:用史蒂夫·乔布斯的话来说微软:It's McDonald's (video)!
这就是我为什么不喜欢使用故事板的原因。其中一些原因也适用于 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
【讨论】:
不喜欢故事板,嗯? :) @logixologist 哈哈,不,不是。在处理有和没有故事板的 iOS 项目后,我得出的结论是我真的不喜欢它们 :) @Rob 虽然听起来我是这么认为的,但实际上我不这么认为。我可以想象有很多方法可以更好地完成 UI 布局,而不是全部用代码手写。我认为我对 Storyboard 最大的批评是它们的实现,而不是它们背后的想法。我概述的大多数要点都可以通过更好的工具和更好的实现来修复(例如,让人类跟踪和理解变化的工具)。当他们改进到利大于弊的程度时,我很乐意再给他们一次机会并改变我的看法。但那一天不是今天:) @Rob 是的,我从来没有抱怨过他们很慢。合并变得更好了,但是如果两个开发人员在故事板的同一区域工作,则很难解决合并冲突:故事板 XML 并不是为人工可编辑而设计的。你是绝对正确的,“一个简单的应用程序,比如 10 个屏幕”可以用 Storyboards 比在代码中更快地完成,我不争辩。然而,只有极少数应用程序如此简单或保持如此简单。如上所述,恕我直言,当您的应用程序增长并变得更加复杂时,您会浪费大量时间使用 Storyboard。 我会在此列表中添加 Interface Builder 文件不太面向未来。我已经将旧的(iOS 5 时代).xib 和 .storyboard 文件打开到现代(iOS 7 时代)Xcode 中,并尝试更新它的外观。 Interface Builder 文件在跨屏幕尺寸和具有较大视觉变化的 iOS 版本(例如 iOS 6 到 7)时通常会损坏。如果 UI 只是在代码中创建,那么这些视觉更新将不会发生许多奇怪的工件和无意识的故事板重新创建。【参考方案2】:我已广泛使用 XIB,并使用 Storyboard 完成了两个项目。我的学习是:
Storyboard 非常适合具有中小屏幕数量且视图之间导航相对简单的应用。 如果您有很多视图并且它们之间有很多交叉导航,Storyboard 视图会变得混乱,并且需要进行太多工作以保持清洁。 对于包含多个开发人员的大型项目,我不会使用 Storyboard,因为您的 UI 文件只有一个文件,并且无法轻松并行工作。 将大型应用程序拆分为多个故事板文件可能是值得的,但我没有尝试过。 This answer 展示了如何在故事板之间进行转场。 您仍然需要 XIB:在我的两个 Storyboard 项目中,我都必须将 XIB 用于自定义表格单元格。我认为 Storyboard 是 UI 实现朝着正确方向迈出的一步,并希望 Apple 能够在未来的 iOS 版本中扩展它们。不过,他们需要解决“单一文件”问题,否则它们对大型项目没有吸引力。
如果我启动一个小尺寸的应用程序并且只支持 iOS5,我会使用 Storyboards。对于所有其他情况,我坚持使用 XIB。
【讨论】:
两件事。 1)您可以在情节提要中制作自定义表格单元(他们称它们为原型单元)和 2)您可以使用多个情节提要文件。请在此处查看我的答案:***.com/a/9610972/937822 了解详细信息。 谢谢。我将链接添加到您的答案。至于自定义单元格:原型单元格对我不起作用,因为我需要在多个视图中重用自定义单元格。所以我不得不恢复到 XIB。 合并故事板在 Xcode 5.x 中得到了显着改进,因为 XML 标记已大大简化。 我认为这完全取决于项目形态(原型?,大型项目?,已经设计好的?等等......)这是我的想法polarios.co/2014/08/04/storyboard-xibs-co “如果你有很多视图并且它们之间有很多交叉导航,故事板视图会变得混乱并且需要太多工作来保持清洁”我不同意这一点,你只需要弄清楚适当的流程来做到这一点,您可以通过适当的设计避免大多数转场。【参考方案3】:创建故事板是为了帮助开发人员可视化他们的应用程序和应用程序的流程。这很像在一个文件中拥有一堆 xib。
有一个类似的问题位于What is the difference between a .xib file and a .storyboard?。
您还可以通过在需要时动态更改的代码创建自定义转换,就像使用 .xibs 一样。
优点:
您无需编写太多代码即可模拟应用程序流程。 更容易看到屏幕和应用程序流之间的转换。 如果需要,也可以将 .xibs 用于情节提要。缺点:
仅适用于 iOS 5+。不适用于 iOS4。 如果您的应用程序的视图非常密集,则很容易变得混乱。何时使用其中一个并没有对错之分,这只是一个偏好问题以及您想要使用的 iOS 版本。
【讨论】:
我知道它们之间的区别以及它们的工作原理我正在寻找有关何时使用一种、另一种或何时同时使用这两种方法的信息。【参考方案4】:我将仅说明 4 个简单的原因为什么您应该使用故事板,尤其是在您必须在产品所有者、产品经理团队中工作的高效环境中,用户体验设计师等
-
Apple 极大地改进了 Storyboard 的使用。 他们鼓励您使用它们。这意味着他们不会通过更新破坏您现有的项目,他们将确保情节提要是未来 XCode/iOS 新版本的证明。
在更短的时间为产品所有者和经理更明显的结果,即使在创建阶段也是如此。您甚至可以将故事板本身用作屏幕流程图并在会议中进行讨论。
即使在应用完成后(这通常是其生命周期开始的地方) - 将来它会更快、更容易地应用小调整。这些很可能同时改变布局的多个方面,您可能希望以所见即所得的方式看到这些方面。另一种方法是在代码中手写 UI 更改,并在 IDE 和模拟器之间来回切换以对其进行测试,每次都等待编译和构建。
可以教非开发人员在情节提要中设置布局并为开发人员创建必要的挂钩(IBOutlets 和 IBActions)。这是一个非常大的优势,因为它让开发人员可以专注于逻辑,而 UX 设计师可以以可视化的方式应用他们的更改,而无需编写任何代码。
我不会写任何缺点,因为约翰内斯已经在他的回答中列出了可能所有可行的缺点。而且它们中的大多数肯定是不可行的,尤其是在 XCode6 的重大改进之后。
【讨论】:
故事板的粉丝,嗯? :)【参考方案5】:我认为您的问题没有正确答案,这只是个人经验和您觉得更舒服的问题。
在我看来,故事板是一件很棒的事情。确实,很难找出您的应用程序在运行时莫名其妙地崩溃的原因,但经过一段时间和经验后,您会意识到它总是与某个 IBOutlet 丢失有关,您将能够轻松修复它。
唯一真正的问题是在版本控制下使用故事板在团队中工作,在开发的早期阶段可能会一团糟。但是在第一阶段之后,完全改变故事板的 UI 更新非常罕见,并且在大多数情况下,您最终会在 xml 的最后部分发生冲突,这些部分是 segue 引用,通常在您重新打开故事板时会自动修复.在我们的团队工作中,我们更愿意处理这个问题,而不是处理具有大量视图代码的重型视图控制器。
我读过很多 cmets 反对自动布局。使用 XCode5,它得到了真正的改进,即使是自动旋转布局也非常好。在某些情况下,您必须在代码中执行某些操作,但您可以简单地输出您需要编辑的约束,然后在代码中执行您需要的操作。甚至为它们制作动画。
我还认为,大多数不喜欢故事板的人并没有完全尝试理解自定义手动 segue 的强大功能,您可以在其中完全自定义(在单个文件中)从一种方式过渡到另一种方式的方式,并且也(有一些技巧)甚至通过更新它的视图内容而不是完全重新加载整个东西来重用以前加载的视图控制器。 最后,您实际上可以做与代码相同的事情,但我认为您可以更好地分离故事板的关注点,但我同意在许多事情上它们缺乏功能(字体,图像作为颜色背景,ecc ... )。
【讨论】:
实际上在使用 XCode 和 Storyboards 之后,我只能说这是一场噩梦,对于你们所有人捍卫它并说它是“伟大的事情”,我说:你们没见过伟大的到目前为止的事情(对于没有去过山的人来说,这就像一座山就是一座山)。更接近伟大的是 android 中可用的东西;使用可视化编辑器可读的 xml 对您有很大帮助,它甚至不是“伟大的事情”,只是任何普通开发人员都希望作为功能基础的东西。 我完全不同意你的观点,在切换到 iOS 之前,我一直是一名 Android 开发人员,我总是会选择 Storyboards 而不是 XML Layouts。对于许多情况(不是所有场景,但适用于大多数场景)来说,这是一件好事,而且我更喜欢它而不是视图控制器中的一堆代码,这些代码肯定不那么直接。最后,这只是意见和场景的问题。 如果我使用 Angular UI 路由器,为什么我需要使用情节提要?【参考方案6】:我没有在我的任何应用程序中使用 StoryBoard 或 XIBs.. 而是以编程方式创建所有内容。
Δ 好处:
√ 您可以为UIView
创建任何复杂类型的 UI 或过渡动画。
√ 支持所有iOS版本。不用担心 √ *您的应用程序将支持您的代码中的所有 iPhone/iPod/iPad 设备。 √ 你总是在更新,因为你知道代码总是有效的。 √ *适用于任何已推出的(新)设备——无需更改代码。 √ 一切由你决定。在某些地方你想改变一些东西——无需查看故事板或 xib。只需在特定类别中搜索即可。 √ 最后但不是列表 - 您永远不会忘记如何以编程方式管理所有内容。这是最好的事情,因为您对控制的了解比任何人都深。 我从来没有发现不使用 SB 或 XIB 的问题,因为我对此很擅长。 * 如果你已经根据屏幕尺寸设置了 UIKit 的对象框架。 附注如果你还没有做这件事——你可能会遇到困难(或者可能会感到无聊),但是一旦你熟悉了——它对你来说真的是一个糖果。
【讨论】:
在没有任何 Storyboard 或 XIB 的情况下,在哪里可以找到基本的“以编程方式创建一切”iOS 和 OSX 应用程序的 Swift 模板/示例?【参考方案7】:如果您想关心 Storyboard 的性能,请观看WWDC 2015 Session 407
构建时间
当界面生成器编译故事板时,它会做两件事 首先,它试图最大化您的应用程序的性能,并且 其次,它还最大限度地减少了创建的 nib 文件的数量。
如果我有一个带有视图和一堆子视图的视图控制器, 界面生成器,构建时将创建一个 nib 文件 视图控制器并为视图创建一个 nib 文件。
通过为视图控制器和视图控制器提供单独的 nib 文件 view,这意味着可以按需加载视图层次结构。
运行时间
当您使用 UI 故事板、API 分配故事板实例时, 最初,您分配内存的只是 UI 故事板 实例本身。
没有视图控制器还没有视图。
当您实例化初始视图控制器时,它将加载 nib 对于那个初始视图控制器,但同样,没有视图层次结构 尚未加载,直到有人真正要求它为止。
【讨论】:
【参考方案8】:我一直在从事一个规模合理的项目(用故事板的说法>20 个场景),并且遇到了许多限制,不得不反复去文档和谷歌搜索做事。
UI 都在一个文件中。即使您创建了多个情节提要,每个情节提要中仍然有许多场景/屏幕。这是中大型团队的问题。
其次,它们不能很好地与嵌入其他容器控制器等的自定义容器控制器配合使用。我们在选项卡式应用程序中使用 MFSlideMenu,并且场景有一个表格。这对于故事板几乎是不可能的。花了几天时间,我采用了完全控制的 XIB 方式。
IDE 不允许选择处于缩小状态的控件。因此,在大型项目中,缩小主要是为了获得高级视图,仅此而已。
我会将故事板用于团队规模较小的小型应用程序,并将 XIB 方法用于中大型团队/项目。
【讨论】:
这三点现在已经完全过时了(谢天谢地)。【参考方案9】:如果你想在多个视图控制器中重用一些 UI,那么你应该使用 XIBs
【讨论】:
以上是关于何时使用 Storyboard 以及何时使用 XIB的主要内容,如果未能解决你的问题,请参考以下文章
何时使用 GetXXX() 方法以及何时使用 Getter 属性
何时使用 .First 以及何时将 .FirstOrDefault 与 LINQ 一起使用?