发布在即!企业 AIGC 应用程度测评,3 步定制专属评估报告。抢首批测评权益>>> 了解详情
写点什么

Storyboard 优雅使用规范

  • 2016-07-25
  • 本文字数:3067 字

    阅读完需:约 10 分钟

Storyboard 是苹果一直推荐使用的界面开发方式。在近几年的 Xcode 更新中可以看出,苹果对 Storyboard 的开发力度也不断增强,添加了更多功能和特性,大大方便了界面的开发、适配以及提升代码性能。

Storyboard 最大的好处就是把界面和代码分离,如同 Web 开发中 CSS 描述界面,HTML 描述内容,JavaScript 描述行为一样,能让代码变得更清晰易读,界面的行为以及相互的逻辑也变得更直观。这对团队开发来说是大大的好事。

在我们准备着手开发 Catfan App 的时候,由于刚好 iOS 9 发布不久,而且 Swift 语言也逐渐稳定成熟,所以决定抛弃以往纯手写或 xib 来构建界面的历时包袱,完全使用纯 Storyboard 来进行开发。

在团队开发中,由于每个成员对 Storyboard 都有不一样的理解,这往往会导致在使用的时候出现各种冲突。这时候就需要要引入一套 Storyboard 的使用规范来避免。

目前使用纯 Storyboard 开发的大型开源项目不多,我们主要参考了 WordPress、Wikipedia 以及 IBAnimateable 官方项目的用法,并且在实践中不断研究探索来进行调整。

Storyboard 分离规范

除非是单页面应用,在大多数情况下,使用单一 Storyboard 往往是不可行的,因为每个 App 通常由各种不一样的复杂模块构成,每当里面的一个元素的属性或位置产生变化,都会导致整个 Storyboard 文件产生多处代码的变动。尤其在 Git 代码版本的控制下,处理分支合并产生的冲突会变得非常麻烦。

所以,把 Storyboard 分离有一个 1 - 5 原则:把每一个 Storyboard 尽量分离成一个人处理范围,每一个 Storyboard 尽量控制少于 5 个 View。例如,设置页面、注册页面、信息详情页、发布页面等,基本上只需要一人就能负责,而且页面大多数情况下都会少于 5 个 View (如果超过 5 个的时候,就可以考虑是不是在里面可以考虑把它们再分离)。把该模块的所有 View 都放在同一个的 Storyboard 文件里进行管理。这样就能大大减少相互冲突的情况,并且 Storyboard 的读取和渲染性能也比单独打开一个大型 Storyboard 的要快不少。

Storyboard 命名规范

一套优秀的代码项目,变量的命名,代码的语言风格都会有一套对应的规范,以便于成员之间进行沟通和开发。在 Storyboard 里面,各种的元素标识同样地也需要一套命名的规范,以便于开发之间的沟通。

尽管我们可以通过元素的 Identity Inspector 页面中的 Label 属性对元素进行强制命名标识。但 Xcode 有一个特性,当元素拖拉到代码处进行 IBOutlet 的变量绑定时候,该元素的标识会自动根据变量的名字进行自动命名,无需在 Label 属性中进行指定。其命名规则是把驼峰写法的变量的每个单词添加空格分隔,并且每个单词的首字母大写。例如:albumCollectionViewController -> Album Collection View Controller,passwordLabel -> Password Label。简单来说,元素标识的命名等同于在代码中的变量名称。

所以,根据这个特性,我们只需要在代码的元素变量命名中应用一套规范,就能同时规范在 Storyboard 中的命名了。

通常情况下,IBOutlet 变量使用【控件作用的名称 + Xcode 控件默认名】来命名会有不少的好处。

例如:

复制代码
album + CollectionView
username + Label
avatar + ImageView
content + TextView
  • 规则简单,可读性强。
  • 自动转化成 Storyboard 的名称,如 Album Collection View、 Username Label、 Avatar Image View 等等,都符合 Xcode 默认的命名规范,显得一致。
  • 在代码中调用方法时,很容易就能识别出该变量在界面中是什么类型的元素,包含什么属性和方法。(当输入 avatarImageView. 的时候,你就能知道它会有 image 这个属性了)

(点击放大图像)

Storyboard 界面规范

Storyboard 除了作为 UI 界面的构建语言之外,还担当着界面预览的角色。界面规范有一个原则,就是当把 Storyboard 展示给其他人的时候,尽量做到能让别人一看就知道这个 Storyboard 是干什么的,界面之间的逻辑是怎样的,界面大致的效果是如何的。

布局规范

Xcode 本身就有就有布局辅助线提示的功能,当进行拖动的时候,可以根据提示的辅助线来进行 View 或控件之间的对齐,合理利用此特性能方便我们调整出整齐的布局。

View 和 View 之间的摆放,可以遵循从左往右,从上到下的原则,进行逻辑排列。因为在 Storyboard 里 View 之间的连线算法都是从 View 的右边缘出发,到另外一个 View 的左边缘结束,如果调转了,就会出现很多交叉的连线,让界面看起来很乱。

其次,View 之间最好也留有足够的间隔,不要太挤,也不需要太远。大概在大于四分之一,小于四分之三 View Contrller 的宽度(默认是 600 * 600)较佳。

在 Xcode 7 里,新增加了 Storyboard Reference 控件(虽然是在 iOS 9 新增加的,但 iOS 8 也可用)。合理使用此控件,能让 Storyboard 描述出 View 与其它 Storyboard 的跳转逻辑。并且可以通过 Segue 来进行 View 之间的数据传递,统一规范 View 之间跳转的代码,让逻辑更清晰。

但总的来说,布局的位置基本上因人而异,没有完全正确的布局方式。只要在摆放的时候,花点时间思考如何让人看起来舒服,有逻辑性,那基本上就能达到目的了。

(点击放大图像)

设置规范

为了达到在 Storyboard 里,能呈现出 View 在运行时大致的界面,在设置 View 与各种控件的时候,同样需要制定一些规范,以达到统一的展示效果。

例如在设置 Label、Text View 等作为内容 Placeholder 的时候,text 属性所填写的最好是实际运行时所呈现内容的例子。如展示用户名的 Lable 就填写 Username,展示时间的 Label 就填写 2010-01-01,展示内容的 Text View 就填写一些 Lorem ipsum dolor sit … 等默认内容之类的。如果不这样区分,界面中一大堆默认的 Label 会是怎样的一种感觉?

(点击放大图像)

对于展示固定内容的 text 属性,那最好都统一基于 Based Language 来设置,否则如果在后期需要对程序进行多国语言化的时候,会非常麻烦。

在新版的 Xcode 里,还新增加了 IBDesignable 和 IBInspectable 两个特性,只需要添加一些代码,就能让 Storyboard 里的控件呈现出更加接近运行时所呈现的效果。有兴趣的,可以参考相关的文章介绍。

(点击放大图像)

(点击放大图像)

全局开发规范

除了上述的规范外,还有更多细节的地方是会可能涉及到整个项目所有 Storyboard 的设置的。例如:

  • 文字字体,字体大小,各元素的颜色
  • 语言定义
  • Autolayout 设置方式
  • 界面自适应设置
  • UITest 相关设置
  • 更多

这些都需要在统一开发之前,预先进行团队协商和定义。最好能把它写成一个团队文档,让所有成员都遵循这个方式进行设定,这样就能减少开发中可能产生的冲突,透过 Storyboard 的方式,让 iOS 开发变得更加便捷。

总结

尽管使用规范会因团队、项目、技术等的不同要素而有所差异。但总的来说,在开发时订立一套团队 Storyboard 的使用规范,将会大大提升项目整体开发的质量以及速度。在我们使用纯 Storyboard 开发的实践中,整个项目几乎没有多少用于构建界面和适配的代码,各个不同 View 之间相互切换的逻辑,都显得非常的清晰易明。

参考

关于作者

黎言卓(Angel Lai),Catfan 与 Medoo 项目的创始人,全栈工程师、设计师,超过 6 年相关经验,关注前端、移动端、以及产品设计领域。本文为作者投稿。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-07-25 18:223620

评论

发布
暂无评论
发现更多内容

C++ primer -- 第18章 探讨C++新标准

Dreamer

c++

C++ primer -- 第十三章 类继承

Dreamer

c++

目标检测综述

Dreamer

TensorFlow 篇 | TensorFlow 数据输入的最佳实践

Alex

tensorflow keras input pipeline dataset

c++ primer -- 第14章 C++中代码重用

Dreamer

c++

架构师训练营第 1 期 第 3 周作业

李循律

极客大学架构师训练营

接口测试人员需要掌握的知识技能

测试人生路

接口测试

C++ primer -- 第十章 对象和类

Dreamer

c++

C++ primer --第十一章 使用类

Dreamer

c++

C++ primer -- 第17章 输入,输出和文件

Dreamer

c++

架构师训练营第 1 期 第 5 周作业

李循律

极客大学架构师训练营

SpringBoot-技术专题-war包部署读取外部配置Properties

洛神灬殇

C++ primer -- 第十二章 类和动态内存分配

Dreamer

c++

C++ primer -- 第十五章 友元,异常和其他

Dreamer

c++

Forsage矩阵系统开发,智能合约搭建

薇電13242772558

Docker底层技术

混沌畅想

Docker 容器 DevOps 底层技术

C++primer-函数探幽

Dreamer

c++

独立显卡市场又一巨头跻入,英特尔锐炬® Xe MAX 独立显卡来了!

E科讯

一个研发团队是如何坚持7年技术分享的?

PingCode

团队管理 程序员 敏捷开发 研发管理 技术分享

架构师训练营 1 期第 6 周作业

木头发芽

面试时说Redis是单线程的,被喷惨了!

redis 编程 程序员 计算机

C++ 第九章 内存模型和名称空间

Dreamer

c++

C++ primer -- 第16章 string类和标准模版库

Dreamer

c++

TypeScript魔法堂:函数类型声明其实很复杂

肥仔John

Java typescript

SpringBoot-技术专题-war包部署读取外部配置Yml

洛神灬殇

MySQL中事务的持久性实现原理

X先生

MySQL 数据库 sql 数据库事务 事务

在2020年更受关注和追捧的JS框架

葡萄城技术团队

react.js Vue js Svelte

Caffe 安装踩坑记录

Dreamer

caffe

写文档太麻烦,试试这款 IDEA 插件吧!

程序员小航

Java markdown IDEA idea插件 文档

EDA最强攻略,如何为EDA选择存储?

焱融科技

分布式 高性能 存储 半导体 EDA

当下工作流管理系统的发展趋势

Marilyn

敏捷开发 快速开发 软件架构 企业开发

Storyboard 优雅使用规范_移动_黎言卓_InfoQ精选文章