在iOS编程中使用Storyboard而不是xib文件有什么好处?

时间:2012-01-31 17:07:02

标签: ios xcode storyboard interface-builder xib

使用Storyboard和xib文件之间有哪些主要区别

具体而言,  使用故事板的优点或缺点是什么?

不幸的是,尽管进行了大量的研究,我在Storyboard上找到的所有内容都是简单的教程,向您展示如何设置故事板,而不是具体的信息来解释它们是什么。

12 个答案:

答案 0 :(得分:83)

故事板是:

  • 所有场景的容器(视图控制器,导航控制器,TabBar控制器等)
  • 这些场景之间的连接和转换管理器(这些称为Segues)
  • 管理不同控制器如何相互通信的好方法
  • 故事板让您可以全面了解应用程序的流程,而这些流程永远无法从单独的nib文件中获取。
  • 当你有几个控制器,每个控制器都有自己的nib文件时,会发生所有“混乱”的缩减器。

我一直在使用Storyboard一段时间,唯一的缺点是你不能以iOS 4或更低版本为目标。故事板仅适用于运行iOS 5或更高版本的设备。除此之外,其好处很多,而且缺点是IMO不存在。

我见过的最好的教程是Ray Wenderlich's

此外,如果您是Apple Developer计划的成员,请查看故事板(iTunesU)上去年的WWDC会议,这很棒。

另一个伟大的(也在iTunesU上)是最新的斯坦福iOS应用程序编程课程。

答案 1 :(得分:52)

不仅是故事板的专业方面,也是缺点 - 只是因为你要求输入:

  • 在团队中使用SB并不容易,因为只有一个参与者可以同时处理SB(因为它是一个文件)。

- 以下情况并非如此: - 如果你需要做SB没有提供的东西,那么将SB与编程创建的视图混合起来并不容易(好吧,尽管如此)

经验法则似乎是:你期望你的项目越复杂,你就越不会选择SB。

编辑: - SB的另一个缺点:解决所有关于SB的XCode烦人的错误。例如。因为几个不一致而不得不频繁刷新DerivedData文件夹。有时故事板文件或其链接已损坏。那么你可能会很高兴找到问题所在。看一下这个thread to get the idea

EDIT 2(2013年3月):同时,Storyboards和Xcode工作得更好,文档和最佳实践也广泛传播。我认为,对于大多数项目,可以推荐使用故事板,即使仍有一些问题。

编辑3(2013年9月):现在使用新的Xcode 5格式与SB合作可能会变得更好,因为它似乎可以merge SB-code much easier now.

另一个编辑:好吧,如果你有一个小时的时间,请坐下来,放松一下listen to these guys discussing this topic (Ray Wenderlich & Co)

编辑2016.1:经过很长一段时间成为故事板的倡导者,我在过去的几个月里一直很麻烦,我决定尽可能地放弃故事板。原因是Apple增加了像傻瓜这样的功能,但并不关心错误和缺陷。具有大量自动布局约束的性能非常糟糕(设计时),并且容易出错的情况变得非常严重。 示例:即使不那么复杂在Xcode中打开项目后,故事板也会立即进入“脏模式”(请参阅​​git状态)。 提示:作为初学者,您会喜欢Storyboard,因为您可以快速创建原型并在没有大量代码的情况下运行。当您进入中间状态时,您将为项目添加更多GUI代码。现在你开始在代码和SB之间来回 - 事情开始变得更糟。迟早你会倾向于在代码中执行大部分GUI工作,因为结果比拥有多个源更容易预测。

答案 2 :(得分:8)

摘要

Nibs / .xib文件和Storyboard都是Interface Builder文件,用于在Xcode中为iOS和Mac应用程序直观地创建用户界面(我将使用iOS术语来表示类,因为这个问题被标记为iOS但它也适用于Mac编程)。

差异

笔尖旨在与单个UIView一起使用。它们也可以通过将File的所有者类设置为UIViewController的任何子类并连接到视图出口(使用Xcode最右侧窗格中的Connections Inspector进行连接来连接)来连接到UIViewController子类。

故事板旨在包含1个或多个UIViewController的用户界面。您可以在单个故事板中构建整个用户界面,也可以将其分成较小的部分。

优点

应始终使用故事板来支持.xib文件/ Nib(对于视图控制器)。故事板具有更多功能,并由Apple积极开发。

支持Nibs的每个论据都依赖于他们单独使用的事实,而故事板包含许多场景。您可以像使用Nib一样轻松地为每个UIViewController使用单个故事板(请参阅下面的代码示例)。请继续阅读以获取详细说明和代码示例。

详细

为什么Storboards优于Nibs?

答案主要归结为Apple鼓励使用Storyboard并将更多的开发工作投入其中。

  1. 故事板具有Nib缺乏的缩放功能。说真的,在小笔记本电脑上设计更大的屏幕时,你无法在Nibs中进行缩放。
  2. Nibs缺少以下关键功能:
    • UITableViewmore info
    • 的原型和动态单元格
    • top layout guide属性(请参阅注释)
    • 如果您要添加到此列表中,可能会有更多内容,请编辑或评论
  3. 您无需设置“文件所有者”类别。
  4. 反对故事板的基本论点是,将所有视图控制器放在一个地方会导致合并冲突,缓慢的Xcode,缓慢的构建时间以及维护对接的一般痛苦。因此,一般建议是为每个UIViewController使用Nib。

    但是......你可以为每个UIViewController创建故事板。一个常见的做法(至少对我来说)是在类方法中隐藏所有UIViewController初始化(因为没有其他类需要知道控制器的Nib / Storyboard所在的文件的名称)。 让我们比较一下可能用来创建这种方法的相关代码片段。单行代码就是两者之间的完全差异。

    目标C

    <强>故事板

    + (ViewController *)create
    {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"ViewController" bundle:nil];
        return [storyboard instantiateInitialViewController];
    }
    

    <强>笔尖

    + (ViewController *)create
    {
        return [super initWithNibName:@"ViewController" bundle:nil];
    }
    

    <强>用法

    - (void)showMyViewController
    {
        ViewController *vc = [ViewController create];
        [self presentViewController:vc animated:YES completion:nil];
    }
    

    夫特

    <强>故事板

    static func create() -> ViewController {
        let storyboard = UIStoryboard(name: "ViewController", bundle: NSBundle.mainBundle())
        return storyboard.instantiateInitialViewController() as! ViewController
    }
    

    <强>笔尖

    static func create() -> ViewController {
        return ViewController(nibName: "ViewController", bundle: nil)
    }
    

    <强>用法

    func showMyViewController() {
        let vc = ViewController.create()
        self.presentViewController(vc, animated: true, completion: nil)
    }
    

    参数

    我将解决Nibs的所有常见论点;正如我之前提到的,主要是赞成单个文件,而不是作为Nibs在Storyboard上的参数

    1. 团队合并
    2. 参数:拥有一个包含大量视图控制器的故事板     如果您正在使用多个团队,则会导致合并冲突     人们做出改变

      响应:单个故事板不会导致合并冲突比单个Nib

      更多
      1. 复杂性
      2. 论证:非常复杂的应用程序在故事板中有很多场景,导致一个巨大的故事板,需要永远加载,因为它的大小几乎无法理解。

        回复:这是一个很好的观点,但您可以轻松地将Storyboard分成更小的部分。 Storyboard References看起来像一个很棒的功能,可用于将故事板链接在一起,但它们仅适用于Xcode 7 / iOS 9+。此外,仍然没有理由在故事板上选择单个Nib。

        1. 可重用性
        2. 参数:为每个UIViewController子类创建一个Nib,可以重复使用代码,这样就不必为故事板中的每个场景设置所有约束和出口。

          回复:同样,没有理由选择单个故事板上的单个Nib。

答案 3 :(得分:5)

几个月前在LiDG会议上发表了nice presentation about Storyboard

就个人而言,我会说这是采用新应用的方式。存在一些差距,特别是对于非常复杂的应用程序,但专业人士的重要性超过了缺点。

答案 4 :(得分:4)

故事板的其他好处:

  • 故事板可以更好地支持tableviews。那是你可以使用的 “动态”和“原型”细胞。
  • 使用故事板实例化视图控制器更容易。你可以这样做:[se lf.storyboard instantiateViewControllerWithIdentifer:]
  • 故事板支持视图控制器容器,因此您可以以图形方式布置子视图控制器。

缺点是:

  • 当故事板包含大量视图控制器时,在XCode中渲染的速度很慢

  • 无法为故事板中的一个视图控制器启用Autolayout。

答案 5 :(得分:3)

请注意,如果您使用Storyboard,则您的应用程序不能与旧版操作系统安装向后兼容。

答案 6 :(得分:2)

故事板基本上是一种让您更轻松地开展工作的设备。它被编译成一系列nib文件,因此性能几乎相同,但作为开发人员,它能够快速查看整个应用程序流程。

我开始转换到在新项目上使用故事板,我可以说服客户接受iOS 5作为最低版本。这纯粹是因为我更喜欢这样做,而且我花更少的时间来完成相同的任务。

答案 7 :(得分:1)

您对自动布局的态度也可能会影响您是否要使用Storyboard。使用xib可以启用或禁用自动布局,基于每个.xib,允许在应用程序中混合使用,而Storyboard将您的选择应用于它们包含的所有视图。

答案 8 :(得分:1)

你会在一秒钟内看到全局。有很多NIB文件,你看不出大局。 更容易维护您的程序。更容易理解其他程序......等等。

答案 9 :(得分:1)

<强>优点:

1)设计接口非常好

2)您可以使用StoryBoard Segues以很酷的方式识别导航/模态关系。

3)如果您的应用支持多种设备,那么这是组织不同视图的好方法。

4)原型设计是另一个额外的优势。

5)原型UITableViewCell可以节省时间并减少代码量。

6)您可以使用StoryBoard在一个地方看到该应用的所有屏幕。

7)您可以轻松查看它们之间的关系

8)如果您正在处理某人的代码,您可以更好地了解该应用程序的流程。

9)您可以通过应用故事板中的视网膜外形设置为iPhone 4和iPhone 5设置用户界面,而无需一次又一次地运行应用程序。

10)客户可以在开始开发之前查看应用程序的原型,这里的故事板可以帮助你。

<强>缺点:

1)仅适用于iOS 5 +

2)StoryBoardSegues有点僵硬,你可以多次使用prepareForSegue。

4)与IB一样,与其他显示引擎和工具包不太友好。

4)难以分享单个视图或一组视图的设计 - 您必须全部或全部发送。

5)对于故事板,你需要一个专门用于iPad的大屏幕。

6)将视图从其他应用复制到故事板时很难。

7)当多个开发人员使用git repository

处理同一个项目时,故事板中的问题

从某些资源中复制

答案 10 :(得分:1)

故事板的弊大于利。以下是从iraycd复制而来的问题列表:

  • 故事板在运行时发生故障,而不是在编译时发生:您在故事板上有错字或在故事板上错了吗?它将在运行时爆炸。您使用了故事板中不再存在的自定义UIViewController子类?它将在运行时爆炸。如果您在代码中执行此类操作,则将在编译期间及早发现它们。 更新 :我的新工具 StoryboardLint 主要解决了此问题。

  • 故事板变得令人困惑:随着项目的发展,故事板越来越难以导航。另外,如果多个视图控制器与多个其他视图控制器有多个关卡,则情节提要很快就会开始看起来像一碗意大利面,并且您会发现自己放大和缩小并在各处滚动查找所要查找的视图控制器寻找并找出什么塞格点在哪里。 更新 :如this article by Pilkythis article by Robert Brown所述,通常可以通过将情节提要板拆分为多个情节提要板来解决​​此问题。

  • 故事板使团队工作更加困难:由于通常项目中只有一个庞大的故事板文件,因此让多个开发人员定期对该文件进行更改可能会令人头疼:更改需要合并并解决冲突。当发生冲突时,很难说出解决方案的方式:Xcode生成情节提要XML文件,并且它的设计并不是以人类必须阅读为目标,更不用说对其进行编辑了。

    < / li>
  • 故事板使代码审查很难或几乎不可能:对您的团队来说,对等代码审查是一件很棒的事情。但是,当您对情节提要进行更改时,几乎不可能与其他开发人员一起查看这些更改。您所能提供的只是一个巨大的XML文件的差异。破译真正改变的内容以及这些改变是否正确或是否破坏了某些东西确实很困难。

  • 故事板阻碍了代码的重复使用:在我的iOS项目中,我通常会创建一个类,其中包含我在整个应用中使用的所有颜色,字体,边距和插图,以使其具有一致性外观:如果我必须为整个应用调整这些值中的任何一个,那就只是一行更改。如果在情节提要中设置了此类值,则将其复制,并在要更改它们时需要查找所有单个出现的值。您很可能会错过其中一个机会,因为故事板中没有搜索和替换内容。

  • 故事板让您完成两次操作:您是否正在构建同时在iPad和iPhone上运行的通用应用程序?使用情节提要板时,通常会有一个iPad版情节提要板和iPhone版故事情节提要。要使两者保持同步,您需要在两个位置进行每个UI或应用程序工作流更改。好极了。 更新 :在iOS 8和Xcode 6中,您可以为iPhone和iPad使用单个Storyboard。

  • 故事板需要不断的上下文切换:我发现自己在代码中的工作和导航速度比故事板快得多。当您的应用使用情节提要时,您会不断切换上下文:“哦,我想在此表视图单元上点击以加载其他视图控制器。现在,我必须打开情节提要,找到合适的视图控制器,创建新的界面到另一个视图控制器(我也必须找到),给segue一个名称,记住该名称(我不能在情节提要中使用常量或变量),切换回代码并希望我不要键入错误的名称这是我的prepareForSegue方法的序号。我希望我能在我现在所在的位置键入那三行代码!”不,不好玩。在代码和情节提要之间(以及在键盘和鼠标之间)切换会很快变老,并且使您减速。

  • 故事板很难重构:重构代码时,必须确保它仍然与故事板的期望值匹配。在情节提要中移动内容时,只有在运行时仍能与您的代码一起使用,您才会发现它。在我看来,我好像必须保持两个世界同步。我的拙见使我感到脆弱和沮丧。

  • 故事板不可搜索:使用情节提要板时,Xcode中的项目范围搜索实际上并不是项目范围内的搜索。它们不包括在搜索中。因此,当您从代码中删除自定义类或对其进行重命名时,您将必须手动浏览情节提要或查看其原始XML,以确保它与代码更改保持一致。不,先生,我不喜欢。 更新 :故事板可以在Xcode 6中搜索。

  • 故事板不那么灵活:在代码中,您基本上可以做任何想做的事情!使用情节提要板,您只能使用代码中的一部分。尤其是当您想对动画和过渡进行一些高级操作时,您会发现自己正在“与情节提要进行斗争”以使其发挥作用。

  • 故事板不允许您更改特殊视图控制器的类型:要将UITableViewController更改为UICollectionViewController吗?还是变成普通的UIViewController?在情节提要中不可能。您必须删除旧的视图控制器并创建一个新的视图控制器,然后重新连接所有segue。进行这样的代码更改要容易得多。

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

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

  • 故事板不允许您为单个视图(控制器)启用自动布局:通过选中/取消选中情节提要中的“自动布局”选项,更改将应用​​于所有情节提要中的控制器。 (感谢SavaMazăre!)

  • 故事板具有更高的破坏向后兼容性的风险:Xcode有时会更改情节提要的文件格式,并且不保证您将能够打开自己创建的情节提要的文件从现在到几年甚至几个月。 (感谢这一点的先进思想。See the original comment

  • 是麦当劳:用史蒂夫·乔布斯(Steve Jobs)关于微软的话说:It's McDonald's (video)

答案 11 :(得分:0)

在iOS 7之前,Storyboard有点整洁但不是必须的。他们解决了许多问题。 iOS 7将平衡倾向于故事板。

对于iOS 8和9,这不再是一个问题:使用故事板了!

故事板的主要缺点是你完全依赖于XCode,你最终可能会花费数小时在XCode错误上转动轮子。但是XCode已经变得更好了,而Storyboard的优势现在太多了,无法忽视。表视图单元原型,大小类,自动布局支持等。

一些提示:

  • 将每个Storyboard视为视图控制器的容器 永远在一起。不要把它想象成你整个的宏大布局 应用
  • 您可能需要多个Storyboard
  • Segues实际上只对最琐碎的用例有用 - 它们对此非常有用。但在现实世界的应用程序中,许多转换将在代码中发生。 那没关系。
  • 编写一个类别以编程方式实例化视图控制器 从故事板,所以你要做的就是让 vc = SomeViewController.create(),该方法处理所有 细节(拉故事板,拉视图控制器故事板 等)。