何时使用 Storyboard 以及何时使用 XIB
是否有关于何时在 iOS 项目中使用 Storyboard 以及何时使用 XIB 的指南?各自的优缺点是什么?各自适合什么情况?
据我所知,当您的视图控制器由动态 UI 元素(如地图图钉)推动时,使用故事板转场并不是那么干净。
Are there any guidelines on when to use storyboards in an iOS project and when to use XIBs? what are the pros and cons of each and what situations do they each suit?
Near as I can tell it's not that clean to use storyboard segues when you have view controllers being pushed by dynamic UI elements (Like map pins).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
2016 年 1 月 12 日更新:现在是 2016 年了,我仍然更喜欢用代码而不是 Storyboard 来布局 UI。话虽如此,故事板已经取得了长足的进步。我已经删除了这篇文章中所有在 2016 年不再适用的观点。
2015 年 4 月 24 日更新:有趣的是,Apple 甚至没有在其最近开源的 ResearchKit 中使用 Storyboards 作为 Peter Steinberger 注意到(在小标题下“界面生成器”)。
2014 年 6 月 10 日更新:正如预期的那样,Apple 不断改进 Storyboard 和 Xcode。适用于 iOS 7 及更低版本的一些要点不再适用于 iOS 8(现在已如此标记)。因此,虽然故事板本质上仍然存在缺陷,但我将我的建议从不要使用修改为有选择地在有意义的地方使用。
即使现在 iOS 9 已经发布,我还是建议
反对在决定是否使用 Storyboard 时要谨慎。以下是我的原因:故事板在运行时失败,而不是在编译时失败:您的 Segue 名称有拼写错误或在故事板中连接错误?它会在运行时爆炸。您使用的自定义 UIViewController 子类在故事板中不再存在?它会在运行时爆炸。如果您在代码中执行此类操作,您将在编译时尽早捕获它们。 更新:我的新工具StoryboardLint 主要解决了这个问题。
故事板很快就会变得混乱:随着项目的发展,故事板变得越来越难以导航。另外,如果多个视图控制器有多个连接到多个其他视图控制器,那么您的故事板很快就会开始看起来像一碗意大利面条,您会发现自己放大和缩小并滚动整个地方以找到您正在寻找的视图控制器并找出哪些 segue 点在哪里。 更新:此问题主要可以通过将 Storyboard 拆分为多个 Storyboard 来解决,如 Pilky 的这篇文章 和这篇文章经过罗伯特·布朗。
故事板使团队工作变得更加困难:因为您的项目通常只有一个巨大的故事板文件,所以让多个开发人员定期更改该文件可能会很令人头痛:更改需要合并并解决冲突。当发生冲突时,很难说如何解决它:Xcode 生成故事板 XML 文件,但它的设计目的并不是人类必须阅读它,更不用说编辑它了。
故事板使代码审查变得困难或几乎不可能:同行代码审查对于您的团队来说是一件很棒的事情。但是,当您对故事板进行更改时,几乎不可能与其他开发人员一起审查这些更改。您所能获取的只是一个巨大 XML 文件的差异。破译真正改变的内容以及这些更改是否正确或是否破坏了某些内容确实很困难。
故事板阻碍代码重用:在我的 iOS 项目中,我通常创建一个类,其中包含我在整个应用程序中使用的所有颜色、字体、边距和插图,以使其具有一致的外观和感觉:如果我必须为整个应用程序调整任何这些值,那么这只是一行更改。如果您在情节提要中设置此类值,则会重复它们,并且当您想要更改它们时需要查找每一个出现的值。您很可能会错过其中一个,因为故事板中没有搜索和替换功能。
故事板需要不断的上下文切换:我发现自己在代码中的工作和导航速度比在故事板中快得多。当您的应用程序使用故事板时,您会不断切换上下文:“哦,我想点击这个表视图单元格来加载不同的视图控制器。我现在必须打开故事板,找到正确的视图控制器,创建一个新的segue到另一个视图控制器(我也必须找到),给segue一个名称,记住该名称(我不能在故事板中使用常量或变量),切换回代码并希望我不会输错名称继续我的prepareForSegue 方法。我多么希望能够在我所在的地方输入这 3 行代码!”不,这不好玩。在代码和故事板(以及键盘和鼠标之间)之间切换会很快变得过时,并且会减慢您的速度。
故事板很难重构:重构代码时,您必须确保它仍然符合故事板的期望。当您在故事板中移动内容时,您只能在运行时发现它是否仍然适用于您的代码。对我来说,好像我必须保持两个世界同步。以我的拙见,它感觉很脆弱,并且阻碍了改变。
故事板不太灵活:在代码中,您基本上可以做任何您想做的事情!使用故事板,您只能执行代码中可以执行的操作的一部分。特别是当您想要使用动画和过渡做一些高级事情时,您会发现自己“与故事板作斗争”才能使其正常工作。
故事板不允许您更改特殊视图控制器的类型:您想将
UITableViewController
更改为UICollectionViewController
吗?或者进入一个普通的 UIViewController ?在故事板中不可能。您必须删除旧的视图控制器并创建一个新的视图控制器并重新连接所有 Segue。在代码中进行这样的更改要容易得多。故事板给您的项目添加了两个额外的负担:(1) 生成故事板 XML 的故事板编辑器工具,以及 (2) 解析 XML 并从中创建 UI 和控制器对象的运行时组件。这两个部分都可能存在您无法修复的错误。
Storyboards 不允许您向
UIImageView
添加子视图:谁知道为什么。故事板不允许您为单个视图(控制器)启用自动布局:通过选中/取消选中故事板中的自动布局选项,更改将应用于故事板中的所有控制器故事板。 (感谢 Sava Mazăre 的这一点!)
Storyboards 破坏向后兼容性的风险较高:Xcode 有时会更改 Storyboard 文件格式,并且不以任何方式保证您能够打开您在几年甚至几个月后今天创建的故事板文件。 (感谢 ideaadvances 的这一点。 请参阅原始评论)
故事板可以让你的代码更丰富复杂:当您在代码中创建视图控制器时,您可以创建自定义
init
方法,例如initWithCustomer:
。这样,您可以使视图控制器内的customer
不可变,并确保在没有customer
对象的情况下无法创建此视图控制器。使用故事板时这是不可能的。您必须等待调用prepareForSegue:sender:
方法,然后您必须在视图控制器上设置customer
属性,这意味着您必须该属性是可变的,您必须允许在没有customer
对象的情况下创建视图控制器。根据我的经验,这会使您的代码变得非常复杂,并且更难以推理应用程序的流程。 更新 9/9/16:Chris Dzombak 撰写了关于此问题的精彩文章。这是麦当劳:用史蒂夫·乔布斯关于微软的话来说:这是麦当劳(视频)!
这些就是我真的不喜欢使用故事板的原因。其中一些原因也适用于 XIB。在我从事的基于故事板的项目中,它们花费了我比节省的时间更多的时间,而且它们让事情变得更加复杂而不是更容易。
当我用代码创建 UI 和应用程序流程时,我可以更好地控制正在发生的事情,更容易调试,更容易尽早发现错误,更容易向其他开发人员解释我的更改,并且更容易支持iPhone和iPad。
不过,我确实同意,在代码中布置所有 UI 可能不是适合每个项目的一刀切解决方案。如果您的 iPad UI 在某些地方与 iPhone UI 有很大不同,那么为这些区域创建 XIB 可能是有意义的。
苹果可以解决上面列出的许多问题,我希望他们也能这么做。
只是我的两分钱。
更新:在 Xcode 5 中,Apple 取消了创建没有 Storyboard 的项目的选项。我编写了一个小脚本,将 Xcode 4 的模板(带有 Storyboard-opt-out 选项)移植到 Xcode 5: https: //github.com/jfahrenkrug/Xcode4templates
Update 1/12/2016: It's 2016 and I still prefer laying out my UIs in code and not in Storyboards. That being said, Storyboards have come a long way. I have removed all the points from this post that simply do not apply anymore in 2016.
Update 4/24/2015: Interestingly Apple doesn't even use Storyboards in their recently open-sourced ResearchKit as Peter Steinberger has noticed (under the subheading "Interface Builder").
Update 6/10/2014: As expected, Apple keeps improving Storyboards and Xcode. Some of the points that applied to iOS 7 and below don't apply to iOS 8 anymore (and are now marked as such). So while Storyboards inherently still have flaws, I revise my advice from don't use to selectively use where it makes sense.
Even now that iOS 9 is out, I would advise
againstto use caution when deciding whether to use Storyboards. Here are my reasons:Storyboards fail at runtime, not at compile time: You have a typo in a segue name or connected it wrong in your storyboard? It will blow up at runtime. You use a custom UIViewController subclass that doesn't exist anymore in your storyboard? It will blow up at runtime. If you do such things in code, you will catch them early on, during compile time. Update: My new tool StoryboardLint mostly solves this problem.
Storyboards get confusing fast: As your project grows, your storyboard gets increasingly more difficult to navigate. Also, if multiple view controllers have multiple segues to multiple other view controllers, your storyboard quickly starts to look like a bowl of spaghetti and you'll find yourself zooming in and out and scrolling all over the place to find the view controller you are looking for and to find out what segue points where. Update: This problem can mostly be solved by splitting your Storyboard up into multiple Storyboards, as described in this article by Pilky and this article by Robert Brown.
Storyboards make working in a team harder: Because you usually only have one huge storyboard file for your project, having multiple developers regularly making changes to that one file can be a headache: Changes need to be merged and conflicts resolved. When a conflict occurs, it is hard to tell how to resolve it: Xcode generates the storyboard XML file and it was not really designed with the goal in mind that a human would have to read, let alone edit it.
Storyboards make code reviews hard or nearly impossible: Peer code reviews are a great thing to do on your team. However, when you make changes to a storyboard, it is almost impossible to review these changes with a different developer. All you can pull up is a diff of a huge XML file. Deciphering what really changed and if those changes are correct or if they broke something is really hard.
Storyboards hinder code reuse: In my iOS projects, I usually create a class that contains all the colors and fonts and margins and insets that I use throughout the app to give it a consistent look and feel: It's a one line change if I have to adjust any of those values for the whole app. If you set such values in the storyboard, you duplicate them and will need to find every single occurrence when you want to change them. Chances are high that you miss one, because there's no search and replace in storyboards.
Storyboards require constant context switches: I find myself working and navigating much faster in code than in storyboards. When your app uses storyboards, you constantly switch your context: "Oh, I want a tap on this table view cell to load a different view controller. I now have to open up the storyboard, find the right view controller, create a new segue to the other view controller (that I also have to find), give the segue a name, remember that name (I can't use constants or variables in storyboards), switch back to code and hope I don't mistype the name of that segue for my prepareForSegue method. How I wish I could just type those 3 lines of code right here where I am!" No, it's not fun. Switching between code and storyboard (and between keyboard and mouse) gets old fast and slows you down.
Storyboards are hard to refactor: When you refactor your code, you have to make sure it still matches what your storyboard expects. When you move things around in your storyboard, you will only find out at runtime if it still works with your code. It feels to me as if I have to keep two worlds in sync. It feels brittle and discourages change in my humble opinion.
Storyboards are less flexible: In code, you can basically do anything you want! With storyboards you are limited to a subset of what you can do in code. Especially when you want to do some advanced things with animations and transitions you will find yourself "fighting the storyboard" to get it to work.
Storyboards don't let you change the type of special view controllers: You want to change a
UITableViewController
into aUICollectionViewController
? Or into a plainUIViewController
? Not possible in a Storyboard. You have to delete the old view controller and create a new one and re-connect all the segues. It's much easier to do such a change in code.Storyboards add two extra liabilities to your project: (1) The Storyboard Editor tool that generates the storyboard XML and (2) the runtime component that parses the XML and creates UI and controller objects from it. Both parts can have bugs that you can't fix.
Storyboards don't allow you to add a subview to a
UIImageView
: Who knows why.Storyboards don't allow you to enable Auto Layout for individual View(-Controller)s: By checking/unchecking the Auto Layout option in a Storyboard, the change is applied to ALL controllers in the Storyboard. (Thanks to Sava Mazăre for this point!)
Storyboards have a higher risk of breaking backwards compatibility: Xcode sometimes changes the Storyboard file format and doesn't guarantee in any way that you will be able to open Storyboard files that you create today a few years or even months from now. (Thanks to thoughtadvances for this point. See the original comment)
Storyboards can make your code more complex: When you create your view controllers in code, you can create custom
init
methods, for exampleinitWithCustomer:
. That way, you can make thecustomer
inside of your view controller immutable and make sure that this view controller cannot be created without acustomer
object. This is not possible when using Storyboards. You will have to wait for theprepareForSegue:sender:
method to be called and then you will have to set thecustomer
property on your view controller, which means you have to make this property mutable and you will have to allow for the view controller to be created without acustomer
object. In my experience this can greatly complicate your code and makes it harder to reason about the flow of your app. Update 9/9/16: Chris Dzombak wrote a great article about this problem.It's McDonald's: To say it in Steve Jobs' words about Microsoft: It's McDonald's (video)!
These are my reasons for why I really don't like working with storyboards. Some of these reasons also apply to XIBs. On the storyboard-based projects that I've worked on, they have cost me much more time than they have saved and they made things more complicated instead of easier.
When I create my UI and application flow in code, I am much more in control of what is going on, it is easier to debug, it is easier to spot mistakes early on, it is easier to explain my changes to other developers and it is easier to support iPhone and iPad.
However, I do agree that laying out all of your UI in code might not be a one-size-fits-all solution for every project. If your iPad UI differs greatly from your iPhone UI in certain places, it might make sense to create a XIB for just those areas.
A lot of the problems outlined above could be fixed by Apple and I hope that that's what they will do.
Just my two cents.
Update: In Xcode 5, Apple took away the option to create a project without a Storyboard. I've written a small script that ports Xcode 4's templates (with Storyboard-opt-out option) to Xcode 5: https://github.com/jfahrenkrug/Xcode4templates
我广泛使用了 XIB,并使用 Storyboard 完成了两个项目。我的经验是:
我认为 Storyboards 是朝着 UI 实现的正确方向迈出的一步,并希望 Apple 在未来的 iOS 版本中扩展它们。不过,他们需要解决“单一文件”问题,否则它们对大型项目不会有吸引力。
如果我启动一个小型应用程序并且只能兼容 iOS5,我会使用 Storyboards。对于所有其他情况,我坚持使用 XIB。
I have used XIBs extensively and completed two projects using Storyboards. My learnings are:
I think Storyboards are a step in the right direction for UI implementation and hope Apple will extend them in future iOS versions. They need to resolve the "single file" issue though, otherwise they won't be attractive for larger projects.
If I start a small size app and can afford iOS5 only compatibility, I would use Storyboards. For all other cases I stick to XIBs.
创建故事板是为了帮助开发人员可视化他们的应用程序和应用程序流程。这很像有一堆 xib 但在一个文件中。
有一个与此类似的问题什么是.xib 文件和 .storyboard 之间的区别?。
您还可以通过代码创建自定义过渡,这些代码将在需要时动态更改,就像使用 .xibs 一样。
优点:
缺点:
何时使用其中一种确实没有对错之分,这只是一个偏好以及您想要使用的 iOS 版本的问题。
Storyboards were created to help developers visualize their application and the flow of the application. It is alot like having a bunch of xib but in a single file.
There is a question similar to this located What is the difference between a .xib file and a .storyboard?.
You can also create custom transitions via code that will change dynamically if needed, much like you can with .xibs.
PROS:
CONS:
There really isn't a right / wrong when to use one or the other, it is just a matter of preference and what iOS versions you are wanting to use.
我将仅说明为什么您应该使用故事板的4个简单原因,尤其是在一个高效的环境中,您必须在产品所有者、产品经理、用户体验设计师的团队中工作, Apple 极大地
我不会写任何缺点,因为约翰内斯已经在他的答案中列出了可能所有可行的方案。其中大多数肯定是不可行的,尤其是 XCode6 的重大改进。
I will just state 4 simple reasons why you should use storyboards, especially in a productive environment where you have to work in a team of product owners, product managers, UX designers, etc.
I won't write up any CONS, since Johannes has already listed probably all the viable ones in his answer. And most of them are definitely not viable, especially not with XCode6's major improvements.
我认为你的问题没有正确的答案,这只是个人经历和你感觉更舒服的问题。
在我看来,故事板是一件很棒的事情。确实,很难找出为什么你的应用程序在运行时神秘地崩溃,但经过一段时间和经验后,你会意识到它总是与某些 IBOutlet 丢失有关,并且你将能够轻松修复它。
唯一真正的问题是在版本控制下与故事板进行团队合作,在开发的早期阶段可能会很混乱。但在第一阶段之后,完全改变故事板的 UI 更新非常罕见,并且在大多数情况下,您最终会在 xml 的最后部分中遇到冲突,这些部分是 segue 引用,通常会在您重新打开故事板时自动修复。在我们的团队工作中,我们更喜欢处理这个问题,而不是使用大量视图代码的重型视图控制器。
我读过很多反对自动布局的评论。使用 XCode5,它得到了真正的改进,即使对于自动旋转布局也非常好。在某些情况下,您必须在代码中执行某些操作,但您可以简单地导出需要编辑的约束,然后在代码中执行您需要的操作。甚至让它们动起来。
我还认为,大多数不喜欢故事板的人并没有完全尝试理解自定义手动转场的强大功能,您可以完全自定义(在单个文件中)从一种方式过渡到另一种方式的方式,并且(使用一些技巧)甚至可以通过更新视图内容来重用以前加载的视图控制器,而不是完全重新加载整个内容。
最后你真的可以做与代码中相同的事情,但我认为你可以更好地分离故事板的关注点,但我同意他们在很多方面缺乏功能(字体、图像作为颜色背景,等等...... )。
I don't think there is a right answer for your question, it's just a matter of personal experience and what you feel more confortable with.
In my opinion, Storyboards are a great thing. It's true, it's really hard to find out why your app is misteriously crashing at runtime, but after some time and experience you'll realize it's always related to some IBOutlet missing somewhere and you'll be easily able to fix it.
The only real issue is working in team under version control with storyboards, in the early stages of development it could be a real mess. But after that first stage, UI updates that completely changes the storyboard are very rare, and in most cases you end up with conflicts in the very last parts of the xml, which are segue references that usually autofix themselves when you re-open the storyboard. In our team work we prefered to deal with this instead of heavy view-controllers with tons of view code.
I've read many comments againts auto-layout. With XCode5 it got really improved, It's really good even for autorotating layouts. In some case you'll have to do something in code, but you can simply outlet the constraint you need to edit and, at that point, do what you need in your code. Even animate them.
I also think that most of the people who dislike storyboards didn't fully try to understand the power of a custom manual segue, where you can totally customize (in a single file) the way you transition from a way to another and also (with some tricks) even reuse a previously loaded view controller by just updating it's view contents instead of fully reload the whole thing.
At the end you can really do the same things as in code, but I think you have a better separation of concerns with storyboards, but I agree that in many things they lack of features (fonts, image as color background, ecc...).
我没有在我的任何应用程序中使用 StoryBoard 或 XIB。而是以编程方式创建所有内容。
Δ 优点:
√ 您可以为
UIView
创建任何复杂类型的 UI 或过渡动画。√ 支持所有iOS版本。无需担心< iOS 5.
√ *您的应用程序将支持您代码中的所有 iPhone/iPod/iPad 设备。
√ 您始终会更新,因为您知道始终有效的代码。
√ *适用于任何推出的(新)设备 - 无需更改代码。
√ 一切由你决定。在某些地方你想改变一些东西——不需要查看故事板或 xib。只需在特定类别中搜索即可。
√ 最后但不是列表 – 您永远不会忘记如何以编程方式管理一切。这是最好的事情,因为你比任何人都更了解控制。
我从来没有发现不使用 SB 或 XIB 的问题,因为我对此很擅长。
* 如果您根据屏幕尺寸设置了 UIKit 的对象框架。
< sub>PS 如果你还没有做过这件事 - 你可能会遇到困难(或者可能会感到无聊),但一旦你熟悉了它 - 它真的适合你。
I am not using StoryBoard or XIBs in my any of the app.. but creating everything programmatically.
∆ Benefits :
√ You can create any complex kind of UI or transition animations for
UIView
's.√ Support all iOS versions. No need to worry about < iOS 5.
√ *Your app would support all iPhone/iPod/iPad devices within your code.
√ You're always updated as you know the code that'll always work.
√ *Will work on any (new) device launched – No need to change in code.
√ Everything is upto you. At certain place you want to change something – No need to look into storyboard or xib. Just search for it in particular class.
√ Last but not the list – You'll never forget that, how to manage everything programmatically. This is the best thing as you know a control very deep then anyone.
I've never find a problem by not using SB or XIBs as I'm good with this.
* if you've set UIKit's object frames according to screen size.
P.S. If you've still not done this thing – you may faced difficulty (or may feel boring) but once you get familiar with this – its really a Candy for you.
如果您想关心 Storyboard 性能,请观看 WWDC 2015 Session 407
构建时间
运行时间
If you are about to care about Storyboard performance, watch WWDC 2015 Session 407
Build Time
Run Time
我一直在从事一个规模相当大的项目(用情节提要的说法来说,>20 个场景),并且遇到了许多限制,并且必须反复查阅文档和谷歌搜索来进行操作。
UI 全部位于一个文件中。即使您创建多个故事板,每个故事板中仍然有许多场景/屏幕。这是中型团队中的一个问题。
其次,它们与嵌入其他容器控制器等的自定义容器控制器不能很好地配合。我们在选项卡式应用程序中使用 MFSlideMenu,并且场景有一个表格。这对于故事板来说几乎是不可能做到的。花了几天时间,我已经采取了完全控制的 XIB 方式。
IDE 不允许选择缩小状态下的控件。因此,在大型项目中,缩小主要是为了获得高级视图,仅此而已。
我会为团队规模较小的小型应用程序使用故事板,并为中型团队/项目使用 XIB 方法。
I have been working on a reasonably sized project (>20 scenes in storyboard parlance), and have come across many limitations and have to repeatedly go to documentation and google searches for doing things.
The UI is all in one file. Even if you create multiple storyboards, you still have many scenes/screens in each storyboard. This is a problem in medium-large teams.
Secondly, they do not play well with custom Container Controllers which embed other container controllers etc. We're using MFSlideMenu in a Tabbed application and the scene has a table. This is almost impossible to do with a storyboard. Having spent days, I've resorted to doing the XIB way where there is complete control.
The IDE does not allow to select controls in zoomed-out state. So, in a large project, the zoom-out is mostly to get a high level view and nothing more.
I would use storyboards for smaller applications with small team sizes and use XIB approach for medium-large teams/projects.
如果你想在多个视图控制器中重用某些 UI,那么你应该使用 XIB
If you want to reuse some UI in multiple view controllers then you should use XIBs