在设计时团队中,UIKIT 的重要性不言而喻,但是从零开始设计一套 UIKIT 并不容易,抛开视觉部分的探索不谈,仅仅是使用 Sketch 进行协作就有很多问题。

在最近一次的工作中,我跟其他设计师一起使用 Sketch Library 来设计了一套完整的 UIKIT,整个过程中我们使用了很多第三方工具来辅助,当项目的第一个阶段完成之后,我们依然存在一些问题,但相比我之前的经历,现在的情况已经好多了。所以这篇文章主要来记录我们在设计过程中遇到的问题,以及我们的应对方案。

设计之外的准备工作

在真正投入到使用 Sketch 绘图之前,前期有两个工作格外重要:

  1. 确定有多少个 Sketch 文件
  2. 每个文件以及组建如何命名

Library 的好处是可以把一份 UIKIT 拆分成多个文件,因为 Sketch 不支持协作,因此每次每个人只能修改一份文件,最后大家合并起来就一份完整的 UIKIT。如何拆分文件成了我们面对的第一个问题。

使用卡片分类来对组件进行分类

把 UIKIT 拆分成多个文件,其实就是对所有的设计组件进行分类,分类的目的就是为了让设计师在实际的使用过程中能够快速找到所需要的组件。整个分类的过程就如同在做网站的到信息架构,「神奇的数字 7」可以作为一根不错的参考。我们一开始决定将文件拆分成 7-9 个即可。

我们可以按照组件的功能来分类(例如导航、通知),也可以按照组件的形态来分类(例如弹窗、工具提示)。这里并没有一种完美的分类方式,只需要团队内部达成一致即刻。

我觉得在设计师团队内部使用卡片分类的方式来对组件进行分类,会是一个不错的方式。不过我们一开始并没有使用这样的方法,造成后期使用的时候有些设计师找不到对应组件的问题。

如果要进行卡片分类,那么第一件事情就是要列出所有需要设计的组建,准备一份组建清单对于前期的规划和后期的查缺补漏相当重要。

同样信息架构中不仅仅有导航的设计,组件的命名也非常重要。我在Material Design Sketch Library中提到一种命名规则,我们依然沿用了这样的命名方式。

所有的组件会按照「集合/类型/子类/尺寸/主题/状态」来进行组合。考虑到目录的宽度和深度,基本不会在某个组件中出现完整的目录结构,他们通常会在某个子目录中进行合并,以平衡深度和宽度。理想的宽度与深度为 7x3,每个目录中有 7 个左右(5–9)的子目录,每个目录最深为 3 层。

设计过程和协作

在确定了命名方式,文件结构之后,接下来就可以进入到设计阶段。跳过一些 UI 的风格探索的过程,我主要说明 Sketch 的协作。

Sketch 本身并不支持多人协作,那么唯一的办法就是每个人负责其中的一部分,如何划分工作内容成为协作的第一个问题,这个问题也很好解决,例如每个人自己挑自己喜欢的部分。

接下里的问题是我们如何将每个人设计完成的文件放在一起,以及什么时候放在一起比较合适。

由于 Sketch Library 并不是独立的多个文件,而是相关关联的文件,特别是一些基础的组件,会经常被引用到其他的组件当中。如果基础的组件延迟了,那么会影响其他的更复杂组件的设计进度。因此合并的速度越快越好,最好是每次制作一个组件就能合并一次。

使用 GIT 作为协作工具

至于同步文件的工具,目前市面上有大量的同步云盘,但我觉得最好的管理方式是 Git。Git 本用来作为代码的版本管理工具,但是同样也适用于管理设计文件。使用 Git 的好处是,可以清楚看到整个设计过程中的记录,这需要良好的 Commit 习惯来支持。同时当出现问题的时候,使用 Git 能够更好的对文件的版本进行控制。如果是使用 Gitlab 之类的工具,也就可以把设计规范顺手写到 Wiki 当中。

但使用 Git 也面临着一些问题:

  1. 设计师要懂命令行
  2. 避免修改冲突
  3. 图形化修改记录
  4. 良好的 Commit

设计师要懂命令行

Git 本身是用于代码的版本管理,最方便的 Git 工具就是直接使用命令行。但对设计师来说这将会是一大挑战,如果团队内部有懂这方面的设计师,那么就会很方便了,如果没有,也可以求助于开发同事。

Git 也有很多不错的图形化工具,简单易用的莫过于 GitHub 的桌面客户端,如果不涉及到冲突处理,日常中使用 GitHub 客户端足以应付了。

当然也有针对 Sketch 专门设计的 Git 工具 Abstract。对于大部分团队来说,Abstract 相当不错。唯一的问题在于由于无法自行部署,如果公司比较注重文件的安全,那么自行部署的 GitLab 也许会更合适。

GitHub 客户端可以处理多数的问题,但遇到一些棘手的问题的时候,还需要命令后,例如设计师 A 需要设计师 B 负责的 file_b.sketch 中的 component_b,但是 component_b 迟迟未设计完成。着急的设计师 A 会自己尝试去修改 file_b.sketch,而这个时候就会引发文件冲突。

当冲突的时候可以使用 Git 命令去解决,但在冲突产生之前,我们也尝试了一些方法来提前避免冲突。

使用 Trello 来管理设计流程

前面提到过在设计开始前,需要准备一份组建清单,Trello 是一个不错的协作工具,将文件清单放在 Trello 上也特别方便。最开始编辑 Sketch 文件时不要着急直接开始设计组件,而应当为每个组件创建一个空的 Symbol 作为占位符。这样以来,当设计师 A 需要用到 component_b 的时候,虽然并没有设计完成,但是已经有一个占位的组件可以先拿来引用,当 component_b 设计完之后再进行同步和后期修改。

即便是再完美的计划也会出现漏洞,有时候需要的组件并没有被提前规划进来,那么后期的合并可能还是会出现冲突。而在编辑文件的时候,避免冲突的方法就是不要去编辑有人正在编辑的文件。我们可以在通讯工具中直接说自己正在修改某个文件,但这样效率太低,而且通讯工具中的杂讯很多,这些消息可能会被快速冲走。

我们使用 Trello 来作为一个状态的指示器。所有的 Sketch 文件都被作为一张独立的卡片放在 Sketch Library 列表中,当需要修改某个文件的时候,需要先去 Trello 上看代表该文件的卡片是否在 Doing 列表,如果在的话,就说明已经有人在修改了。卡片上的成员可以知道是谁正在修改这个文件。如果比较着急可以直接找到该设计师并让他一并修改自己遇到的问题,然后尽快 Push 一次。如果没有人在编辑,则在编辑前先把卡片移动到 Doing 列表,并把自己加入到卡片的成员当中。当完成修改并且 Push 之后,可以把自己从卡片中移除,并把卡片移动到 Library 列表。

从准备清单到添加占位符,再到使用 Trello 来指示文件的编辑状态,这些都无法百分百避免文件的冲突,因此当出现问题的时候,能够有人帮忙解决问题就非常重要了。

图形化修改记录

前面提到的 Abstract 由于针对 Sketch 文件进行专门的优化,因此每一次的修改都能想看代码那样直观的看出修改了哪些地方。好在 Sketch 中的 Git 插件也可以实现类似的功能,虽然也存在一些问题,但效果还是很不错的。

Sketch Git 的 diff 效果

Sketch Git 插件需要在保存之后通过插件进行 Commit,并且勾选「Generate files for pretty diffs」,如下图所示。

在 Sketch 中进行 Commit

Push 之后就可以在 History 里面看到修改的内容。

Sketch Git 确实可以帮助我们更好的了解文件的修改记录,但是每次都要点击 Commit 详情才能查看,因此 Sketch Commit 只能作为一个辅助工具,更重要的是,撰写清晰易懂的 Commit 内容。

COMMIT 的规范

关于 Commit 的建议写法,可以参考Udacity Git Commit Message Style Guide。虽然是针对代码而言,但是对设计师来说,其中的规范也是可以借鉴的。

我们并没有对这方面进行规范化,因此也造成虽然可以看到很多修改的 Commit 记录,但实际上并不知道到底该了什么,甚至是打开文件你都很难意识到到底修改了什么部分。

清楚的记录修改了哪些部分,对于文件后期的维护非常重要,因为组件之间的相互紧密的关联性,每一次改动都会对其他关联的文件造成影响,因此当改动之后,应当去检查所有引用了该组件的文件。

我期望通过 Sketch 插件能够建立一套自动建立引用索引的机制,但目前为止尚未开发出来。

后续的维护

在最初设计的时候,我们期望能够一次性就做到最好,尽量避免后期不断的改动。所有人都会有这样的想法,避免改动,殊不知这世界上唯一不变的就是不停的改变。因此以「避免改动」为目标的设计本身就是荒谬的,既然改变不可避免,那么设计的时候应当注意的是「如何更好的改变」。也就是当需要改变的时候,我们的设计方式能够支撑的起这种变动。

而我前面所说的流程,都是以更好的改变作为目标,但我们需要改变的时候,结合以上的工具,能够修改变得更加轻松。

在设计过程中会出现很多重复性的工作,例如修改图层名称,批量修改尺寸或者颜色什么的。文件越是复杂,这样的工作就会越多,避免复杂并不是设计目标,如何理解复杂才是。重复性的劳动可以通过使用 Sketch 插件来完成,我在设计的过程中自己写了三个插件,包括自动修改图层名称、自动标注图层颜色、自动排列图层、自动标注引用的图层。但这些插件都严格按照项目的文件结构来设计,因此无法通用化。

插件是 Sketch 非常强大的部分,特别是在后续的维护当中,可以最大限度的减少工作量。但是制作插件需要时间,同时也需要很清楚的了解背后的逻辑,因此我们在设计过程中会不断的记录中重复劳作,有些可以利用现有的插件解决,有些虽然也是重复劳作,但只是暂时的。那些需要长期使用,并且没有现成插件的重复动作,可以在开发的帮助下写成插件,来提升整个设计团队的效率。