作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
我经常听到 iOS开发者 问一些相同关键问题的变体:
在iOS中开发UI的最佳方式是什么:通过故事板、nib还是代码?
这个问题的答案, 或明或暗, 倾向于假设存在一个互斥的选择, 一个经常被预先处理的问题, 在开发之前.
我认为答案应该是一个或多个 计数器 问题.
让我用一个离题的例子来解释. 比如说我想买一辆车,我问你一个简单的问题:“什么是最好的选择??”
你真的能通过提出一个模型来回答这个问题吗 品牌? 不太可能,除非你建议开法拉利. 相反,你可能会用其他几个问题来回答,比如:
很明显,根本就没有 好 or 坏 汽车,除非它被放置在适当的环境中——根据特定的需求,只有好车或坏车.
就像我们的汽车询价一样 “开发iOS UI的最佳方法是什么?” 问题缺乏背景. 令人惊讶的是,答案不一定是一个包罗万象的案例.
一般来说, 您可以采用三种类型的用户界面设计方法, 每一种都有其利弊, 它的支持者和反对者:
这些选择都不普遍 更好的 比其他任何一个(不管你可能听到什么).
故事板,例如,是iOS UI工具包的最新成员. 我被告知它们是未来,它们将取代nib和自定义代码ui. 我认为故事板是一个有用的工具,但并不是 更换 作为一个 补充 用于nib和自定义代码. 故事板在某些情况下是正确的选择,但不是所有情况.
进一步, 当您可以在同一个项目中使用所有选项时,为什么要静态地坚持使用单个选项呢?, 选择最适合手头特定问题的机制?
这是一个可以, 在我看来, 泛化的:在更高层次上泛化的, 他的答案在我的软件开发原则列表中排名很高: 世界上没有通用的语言, 框架, 或者技术是每个软件开发问题的通用最佳选择. iOS UI设计也是如此.
在这个iOS UI设计教程, 我们将探索这些方法中的每一种,并介绍它们应该使用和应该使用的用例 不 被雇用,以及它们可以混合在一起的方式.
一个典型的新手错误是创建一个大型的项目范围的iOS故事板. 我刚开始的时候也犯过这个错误 使用故事板 (可能是因为这条路很诱人。). 如果你需要在继续之前了解基本知识,你可以咨询苹果公司 iOS storyboard教程.
顾名思义,故事板是一个 带着一个故事登机. 它不应该被用来把不相关的故事混合成一大卷. 故事板应该包含逻辑上彼此相关的视图控制器——这并不意味着 每一个 视图控制器.
例如,在处理以下问题时使用故事板是有意义的:
与此同时, 应该避免使用大型故事板, 包括单个应用程序范围的故事板(除非应用程序相对简单). 在我们深入讨论之前,让我们看看原因.
大故事板, 除了难以浏览和维护, 给团队环境增加一层复杂性:当多个开发人员同时在同一个故事板文件上工作时, 源代码控制冲突是不可避免的. 故事板在内部表示为文本文件(XML文件), 实际上), 合并通常是非琐碎的.
当开发人员查看源代码时,他们会赋予其语义含义. 手动合并时, 他们能够阅读和理解冲突的双方,并采取相应的行动. 故事板, 而不是, XML文件是由Xcode管理吗, 而且每行代码的含义并不总是容易理解的.
让我们举一个非常简单的例子:假设两个不同的开发者改变了a的位置 UILabel
使用自动布局(), 后者推动了他的改变, 产生这样的冲突(注意冲突) id
属性):
的 id
它本身并没有提供任何关于它真正意义的指示, 所以你没什么可做的了. 唯一有意义的解决办法是选择冲突双方中的一方,抛弃另一方. 会有副作用吗? 谁知道? 不是你.
来缓解这些iOS界面设计问题, 在同一个项目中使用多个用户故事板是推荐的方法.
故事板最好与多个相互连接的视图控制器一起使用, 因为它们的主要简化是在视图控制器之间的转换. 在某种程度上, 它们可以被认为是带有视图控制器之间的视觉流和功能流的nib的组合.
除了简化导航流程, 另一个明显的优点是它们消除了弹出所需的样板代码, 推, 现在, 然后解散视图控制器. 此外,视图控制器是自动分配的,所以不需要手动分配 alloc
和 初始化
.
最后, 而故事板最适合用于涉及多个视图控制器的场景, 使用故事板也是合理的 单 表视图控制器的三个原因:
有人可能会说,也可以使用nib设计多个单元格模板. 事实上, 这只是一个偏好问题:一些开发人员更喜欢将所有东西放在一个地方, 而其他人则不在乎.
有几个例子:
在这些情况下,我们可以把视图留在故事板之外或者嵌入到视图控制器中. 前者破坏了故事板的视觉流, 但不会对功能或发展产生任何负面影响. 后者保留了这种视觉流, 但是它需要额外的开发工作,因为视图没有集成到视图控制器中:它只是作为一个组件嵌入, 因此,视图控制器必须与视图交互,而不是实现它.
现在我们知道故事板在iOS中什么时候有用了 用户界面设计, 在我们继续本教程中的nib之前, 让我们来看看它们的一般优点和缺点.
直观地, 你可以假设当一个故事板被加载时, 它的所有视图控制器都会立即实例化. 幸运的是,这只是一个抽象概念 不 实际实现为True:相反,只创建初始视图控制器(如果有的话). 其他视图控制器是动态实例化的, 要么在segue执行时执行,要么在代码中手动执行.
故事板简化了用户界面的原型和模拟 和 流. 实际上, 使用斯威夫特故事板和几行代码就可以很容易地实现带有视图和导航的完整的工作原型应用程序.
当涉及到移动或复制时,iOS故事板的定位很差. 故事板必须与其所有依赖的视图控制器一起移动. 换句话说, a 单 视图控制器 can不 be individually extracted 和 reused elsew在这里 作为一个 单 independent entity; it’s dependent on the rest of the 故事板 to function.
当应用程序转换时,数据通常需要在视图控制器之间传递. 然而, 在这种情况下,故事板的视觉流被破坏了,因为在Interface Builder中没有发生这种情况的痕迹. 故事板负责处理视图控制器之间的流,而不是数据流. 因此,目标控制器必须用代码配置,覆盖视觉体验.
在这种情况下,我们不得不依靠 prepareForSegue:发送方
,使用如下的if/else-if框架:
- (void) prepareForSegue:(UI故事板Segue *)segue sender:(id)sender {
NSString *identifier = [segue identifier];
if ([identifier isEqualToString@"segue_name_1"]) {
MyViewController *vc = (MyViewController *) [segue destinationViewController];
(vc setData: myData);
} else if ([identifier isEqualToString@"segue_name_2"]) {
...
} else if ...
}
我发现这种方法容易出错,而且不必要地冗长.
nib是执行iOS界面设计的老方法.
在这种情况下,“旧的”并不意味着“坏的”、“过时的”或“废弃的”。. 事实上, it’s important to underst和 that iOS故事板 aren’t a universal 更换 for 傲慢的人; they just simplify the UI implementation in 一些 情况下.
与上司, 可以设计任意视图, 开发人员可以根据需要将其附加到视图控制器上.
如果我们将面向对象的设计应用于我们的ui, 那么将视图控制器的视图分解为 不同的模块, 每个都实现为带有自己NIB文件的视图(或者将多个模块分组到同一个文件中)。. 这种方法的明显优点是每个组件都更容易开发, 更容易测试, 更容易调试.
nib分享了我们在故事板中看到的合并冲突问题, 但程度较轻, 因为NIB文件的操作规模较小.
所有用例的一个子集是:
与此同时……
您应该避免在以下情况下使用nib:
更一般地说,让我们来看看使用nib的优缺点.
当跨多个类共享相同的布局时,nib会派上用场.
作为简单的用例, 包含用户名和密码文本字段的视图模板可以用假设的实现 TTLoginView
和 TTSignupView
视图,这两个视图都可以来自同一个NIB. 的 TTLoginView
必须隐藏密码字段吗, 并且两者都必须指定相应的静态标签(例如“输入您的用户名”和“输入您的密码”), 但是标签将具有相同的基本功能和相似的布局.
傲慢的人是 延迟加载,所以他们只有在必要的时候才会使用内存. 虽然这可能是一个优势, 延迟加载过程有延迟, 这也是一种不利因素.
任何 iOS界面设计 这可以用故事板完成,nib也可以用原始代码实现(曾经有一段时间), 当然, 当开发人员没有这么丰富的工具时).
也许更重要的是, nib和故事板无法完成的事情总是可以通过代码提供来实现, 当然, 技术上是可行的. 另一种看待它的方式是nib和故事板是用代码实现的, 所以它们的功能自然是一个子集. 让我们直接进入正反两方面.
以编程方式创建iOS UI的最大优势: 如果您知道如何编写用户界面,那么您就知道幕后发生了什么,而nib和故事板则不一定如此.
做个比较:计算器是一个有用的工具. 但知道如何手动执行计算并不是一件坏事.
这并不局限于iOS,也适用于任何可视化的RAD工具.g., Visual Studio和Delphi,仅举几例). 可视化HTML RAD环境代表了一种典型的边界情况:它们用于生成(通常编写得很差的)代码, 声称不需要HTML知识, 一切都可以用视觉来完成. 但是没有一个web开发人员会在不动手的情况下实现一个网页:他们知道手工处理原始的HTML和CSS会导致更多的模块化, 更高效的代码.
So, 掌握iOS用户界面的编码可以让你更好地控制和了解这些部分是如何组合在一起的, 这提高了你作为开发人员的上限.
在某些情况下,自定义iOS代码是UI设计的唯一选择. 动态布局, 视图元素在哪里移动,流或布局根据内容进行显著调整, 都是典型的例子.
而nib和故事板在合并冲突中遭受了严重的损失, 代码没有同样的错误. 所有代码都具有语义意义,因此解决冲突并不比通常困难.
在你真正看到一个布局之前,很难弄清楚它是什么样子的. 进一步, 你不能直观地定位视图和控件, 因此,将布局规范转换为有形视图可能需要更长的时间, 而nib和storyboard会给你一个事物如何渲染的即时预览.
重构很久以前编写的代码或其他人编写的代码也变得更加复杂:当元素被定位并使用自定义方法和幻数动画时, 调试会话可能会变得非常困难.
在性能方面, 故事板 和 傲慢的人是 subject to the overhead of loading 和 parsing; 和 in the end, 它们被间接地转换成代码. 不用说,这种情况不会发生在代码生成的ui上.
任何以编程方式实现的视图都可以以可重用的方式设计. 让我们来看几个用例:
使用nib和故事板,同样的UI设计过程会复杂得多. 模板文件不允许继承,可能的解决方案仅限于以下几种:
在iOS用户界面设计中使用自定义代码通常是一个好主意,当你有:
通常,代码生成的ui可以 总是 被使用. 他们很少是个坏主意,所以我要加一个
尽管nib和故事板带来了一些优势, 我觉得列出一个列表来阻止代码的使用并没有什么合理的缺点(除了, 也许, 懒惰).
故事板、nib和代码是构建iOS用户界面的三种不同工具. 我们很幸运能拥有他们. 编程ui的狂热者可能不会考虑另外两个选项:代码让您完成技术上可能的所有事情, 然而,其他选择也有其局限性. 对于其他的开发者来说, Xcode军刀提供了三种工具,可以同时使用, 在同一个项目中, 有效地.
你会问怎么做? 不管你喜欢什么. 以下是一些可行的方法:
最后,让我们看最后一个将所有内容联系在一起的例子.
假设我们想要开发一个具有几个不同视图的基本消息应用程序:
此外,我们希望视图的流程如下:
为了实现这款iOS应用,我们的三个UI工具都会派上用场,我们可以使用:
一个真正基本的模型可能是这样的:
至此,我们概述了一个合理的 复杂的iOS应用程序 谁的核心观点将我们的三个主要方法联系在一起 用户界面设计. 记住:不存在二元决策,因为每种工具都有其优点和缺点.
在本教程中,故事板显著地简化了 iOS UI设计和视觉流程. 的y also eliminate boilerplate code; but all this comes at a price, paid in flexibility. 与此同时,nib通过专注于单个视图提供了更大的灵活性,但没有视觉流. 最灵活的解决方案, 当然, 是代码, 这往往是相当不友好和固有的非视觉.
如果你对这篇文章感兴趣,我强烈推荐你观看 伟大的辩论 来自Ray Wenderlich,花了55分钟讨论nib、故事板和代码制作的u.s..
最后,我想强调一点: 尽量避免使用不合适的iOS UI设计工具. 如果一个视图不能用故事板设计, 或者是否可以用nib或代码以更简单的方式实现它, 不 使用故事板. 类似地,如果一个视图不能使用nib设计,就不要使用nib. 这些规则虽然简单,但将对你作为开发人员的教育大有帮助.
拥有20年以上各种技术经验的多面手, 现在主要关注iOS, 斯威夫特, Objective C和后端
世界级的文章,每周发一次.
世界级的文章,每周发一次.