在 2023 年 11 月,我们发布了对智能布局的重大升级,在本系列文章中,我们将回顾幕后故事,看看我们是如何实现它的。在第一篇文章中,团队为这项工作奠定了基础。在第二篇文章中,他们描述了修复问题以及提高可靠性和可预测性的过程。在本期最后一期中,他们解释了如何让智能布局在符号之外焕发新生。
在让智能布局变得更加可靠之后,我们就为最终目标做好准备:将其从符号中解放出来,并带到组和画板中。
这并不像看起来那样简单:我们不能简单地用一个开关来让智能布局在符号之外工作,就像在符号内部一样。这是因为组和画板有两个特点,使它们与符号有所不同
- 它们不会对人们可以在其中编辑的内容施加任何限制。
- 它们缺乏符号源提供的永久参考点。
这些方面构成了我们在该项目中面临的大多数挑战的基础。
除此之外,我们知道我们还需要考虑智能分布,并为整个智能布局引入一些急需的便捷更新。但让我们首先更详细地探讨这两个具有挑战性的特征。
让我们从探索每个领域带来的挑战开始。
探索挑战
挑战 1:符号之外的创作自由
对于符号中的智能布局,只有两个主要操作会导致设计人员可以执行的布局更改
- 间接调整图层大小(由于文本覆盖或替换嵌套符号)
- 隐藏和显示嵌套符号
由于符号之外的编辑没有这些限制,我们必须考虑所有可能导致布局重排的图层更改方式,这些方式可分为三个熟悉的领域
- 调整图层大小——直接通过调整图层或其祖先组的大小,或间接通过更改单个文本或线条大小属性等。
- 添加新图层——通过插入全新的图层,使用⌘D或⌥-拖动复制现有图层,或粘贴剪贴板中复制或剪切的图层。
- 删除图层——通过正常的删除或剪切方法。
挑战 2:在没有源的情况下保持一致性
我们的基本目标之一是使智能布局的整体体验保持一致性和可预测性,无论您是在符号、组还是画板内部使用它。
特别是,当我们将它应用于组时,一个基本的智能布局原则仍然应该有效:只有大小的更改才会影响布局,位置的更改永远不会影响布局。
但还有一个额外的困难:与符号中的智能布局相比,没有“源”,没有原始状态可以查看或从中获取测量值。一旦有人对组的子图层进行更改,原始状态就消失了。没有像符号源那样的原始副本。
这种困难是行为中一些细微不一致性的主要原因。因此,像隐藏子图层这样的操作不会影响布局,因为恢复相邻子图层布局的信息丢失了(一旦通过隐藏删除相邻空间中最小的空间,并且布局发生改变,就没有办法恢复该信息)。
为了记录行为并确保未来的更改不会破坏它,我们大多数现有的单元测试都获得了与组相关的对应测试,因此与智能布局相关的单元测试总数几乎增加了一倍。
响应操作
在确定了挑战之后,我们开始处理设计人员可能会对图层进行的三个方面的更改:调整大小、删除和插入。让我们详细了解每个方面。
调整图层大小时会发生什么?
符号中的智能布局只有一个触发器:更改覆盖会导致图层大小发生更改(在本场景中,让我们先不考虑通过覆盖来隐藏和显示嵌套符号)。
然而,对于组中的智能布局,触发器更多
- 您可以直接调整图层大小,方法是拖动画布,在检查器中设置特定值,或拖动检查器中大小部分的 W 或 H 符号。
- 您可以间接调整图层大小(例如,通过更改文本内容或文本属性,包括通过检查器进行更改)。
- 您可以将符号实例的大小调整为适合。
- 您可以用另一个符号实例替换符号实例。
因此,在进行任何更改之前,我们需要在更多地方进行快照。智能布局已经适用于符号内的组,因此对于检查器,我们“只需要”为普通组也显示相同的智能布局控件。
通过拖动画布或检查器控件进行调整大小,带来了额外的挑战:我们需要确定在更改之前何时进行快照。我们有两个选择:在拖动开始之前进行一次快照(并将所有更改视为相对于该快照的相对更改),或将每个拖动步骤视为单个更改。
后一种方法的主要问题是,未更改图层与更改图层之间的空间关系可能会在布局轴线上发生变化,从而导致拖动过程中的行为发生变化。一个以前不受更改图层影响的图层,可能会突然调整大小——这太不可预测了,所以我们放弃了它。
下面的动画展示了两种方法之间的区别
我们在拖动时对快照的两种潜在方法,让我们在一致性和可预测性方面找到了一个明显的赢家。
删除图层时会发生什么?
删除具有智能布局的组的子图层,与隐藏嵌套符号实例非常相似。因此,我们采用了相同的行为,包括删除最小的相邻间距。
任何重叠的(具体来说,是在布局方向上重叠尾部的)未更改的兄弟图层将被缩短已删除图层的宽度。虽然在未更改的图层重叠两端时这是可取的,但如果重叠的图层在布局轴线上更小,则可能会弄乱布局。
在开发过程中,看似无害的删除操作可能会导致布局混乱,这促使我们引入了暂停智能布局的功能。有了它,设计师可以选择删除图层而不影响布局,并在之后恢复智能布局(稍后详细介绍)。虽然这解决了问题,但我们希望让它更智能,而不是完全依赖暂停作为解决方法。
最终,我们决定让删除的图层只影响完全包裹着它的(沿布局轴)不变图层。部分重叠的图层不会受到影响。在下例中,删除灰色背景图层不会将部分重叠的图层缩小为零——它们现在不受影响。
删除灰色背景图层不会影响其中间的重叠图层。
插入图层时会发生什么?
在具有智能布局的组中插入新的子图层类似于显示嵌套的符号实例,但有一个主要区别:我们没有关于新图层精确位置的信息,以及其新的兄弟图层需要移动多远才能适应它。
与隐藏嵌套的符号实例相反,删除总是导致我们丢失信息(刚删除的较小间距有多大?)。插入,作为其对应项,没有办法从当前布局中推导出该信息。只有一个解决方法:设计师需要决定新兄弟图层应该如何放置。
我们插入图层的方法包括预测可能的插入位置并显示其标记。
我们提供了三种可能的插入位置:两个图层之间、接触前一个图层或接触下一个图层(沿布局方向)。虽然接触位置只是插入图层,没有额外的空间,但中间位置也会添加一些空间,因此在插入图层后,它将被它被放置在左侧和右侧(或顶部和底部,分别)相同的空间包围。无论如何,如果需要,很容易自由地重新定位该图层。
除了从组外放入新图层外,还可以通过复制或粘贴组内现有的子图层来插入图层。
完善体验
当我们在内部版本中开始在组和画板内实现功能时,我们很快意识到我们想以三种主要方式完善智能布局体验
- 设置——让启用、禁用和设置方向变得轻松,无需停止您的工作流程。
- 暂停——让您可以在组或画板内进行更改时暂时停止布局重排。
- 堆叠——包括对堆叠式布局(均匀间距的图层行或列)的特殊调整,即使智能布局并不严格限制于它们。
让我们更详细地讨论这些内容。
加速设置
使用智能布局设置组需要三个步骤
- 选择一些图层
- 将这些图层分组
- 为组选择水平或垂直布局,然后(可选)更改其方向。
作为独立的操作,这些步骤感觉像是一项繁琐的任务,打断了设计流程。我们希望将它们压缩成一个感觉起来像一个快速操作的东西,并避免在这个过程中将人们带到检查器。
我们首先解决了第三步,很自然地转向了键盘快捷键。但是,拥有六种选择(2 个轴 × 3 个方向)加上禁用布局的选项,无法用标准键盘快捷键来表示。
我们环顾四周,寻找具有类似选择的其他操作,这些操作具有快捷键,对齐就是一个很好的例子。对于对齐,我们使用⌃⌘ 接着 ↑ ↓ ← → H 或 V。我们喜欢使用这些键的自然感觉,但想要避免使用某些修饰键组合来表示快捷键“基础”,人们只需要记住它,没有明显的助记符。
因此,我们决定在 Sketch 中首次使用我们称之为“两阶段”快捷键。
- 首先,按住并释放 ⌘L (L 代表 Layout)
- 然后,按下 ↑ ↓ ← → H 或 V 来设置布局方向
- 或者,再次按下 L 来禁用布局(因为您的手指已经放在那里)。
用于使用您的选择设置布局和方向的两阶段快捷键。
我们发现这非常容易上手:您只需要记住 ⌘L(足够简单),其他就像对齐一样。此外,虽然它是一个两阶段快捷键,但它感觉起来像一个单一的操作,涵盖了启用布局、更改轴/方向或完全禁用布局。
最后,解决第二步:将图层分组。这要容易得多:如果您的选择中包含未分组的图层,当您按下 ⌘L 时,我们将作为一种便利操作为您将这些图层分组。
最后,我们认为我们成功地将这三个不同的步骤压缩成了一个感觉起来易于记忆且快速使用的东西:选择您的图层,按下 ⌘L,并选择一个方向,继续。
允许暂停
管理式布局系统既是福也是祸。一方面,它们在自动化方面非常有用,可以使布局保持您预期的方式。另一方面,这种自动化有时会在您不希望的时候出现,并且无意中造成多米诺骨牌效应。
对于智能布局来说尤其如此,因为它会对任何深度的更改做出反应,并且因为它适应任何布局排列,鼓励设计师摆脱均匀结构的布局。
在我们的内部版本中,我们的设计师很快就发现自己偶尔想要这样做,但发现系统一直跟着他们,难以脱身。我们试图让禁用智能布局变得更容易,但这感觉不对,因为设计师经常希望系统在他们完成对外的更改后重新启动。
因此,我们创建了一种暂停智能布局的方法:按下 ⌥⌘L,它将停止对您所做的任何更改进行调整。您可以再次按下它来恢复,但您清除选择后它会自动恢复。因此,您确切地知道智能布局何时暂停,画布底部的提示会显示这一点,您也可以将其关闭以恢复。
在您需要的时候它就在那里,但在您不需要的时候它就不在。
使用智能分布
正如我们在第一篇文章中提到的,尽管智能布局的一个关键原则是在支持任何布局排列,但堆叠排列(均匀间距的单列图层行或列)非常受欢迎——因此,我们想要更好地适应它们。
我们一直都有一个智能分布功能,正是为了让使用堆叠布局变得更容易。它可以帮助设计师调整均匀间距的选择或图层组中所有图层之间的间距,并轻松地重新排列这些图层。此外,我们的整理功能只需单击一下即可创建均匀的堆叠排列,并提供轻松更改间距的选项。
即使我们什么也不做,如果具有智能布局的组的图层以均匀堆叠的方式排列,我们的智能分布功能也可用。我们还知道,用户不一定能够区分这两个功能,也不应该这样做——它们应该都能正常工作。因此,我们着眼于改进这两个功能在自然发生时的协作方式。
智能布局和智能分布无缝融合在一起。
首先,我们让堆叠布局变得更容易。以前,如果您想使用特定的水平或垂直间距值来均匀间距图层,您需要先按下整理,然后调整值。我们让您可以直接输入值,节省了额外的点击。
其次,我们让重新排列堆叠和调整其间距变得更容易。以前,只有在选择组本身的情况下,您才会在画布上看到用于智能分布的句柄。我们知道,这在智能布局中会很烦人,因为您想要选择堆叠中的图层以调整其大小(并让布局适应),然后调整其间距和/或在堆叠中重新排列它。现在,当您选择均匀间距组中的图层时,画布上的智能分布句柄也会出现,以及检查器中的水平和垂直间距值。
最后,我们确保智能布局能够保持整理的整洁。智能布局在将图层添加到堆叠中时会考虑到堆叠的间距,无论是在复制图层还是从外部放入图层时。此外,调整堆叠的间距会导致布局适应。
发布更新
就像我们在制作智能布局更可靠时采用的发布策略一样,我们一有机会就将组中的智能布局作为实验性功能发布。即使它并不完美,它也让设计师有机会使用它并提供宝贵的反馈,因为我们继续朝着公开发布迈进。
再次,正如我们在之前的帖子中提到的,我们要感谢我们社区论坛中那些精彩的人,他们在我们整个组中的智能布局作为实验性功能可用的时间段内分享了他们的体验。这些反馈帮助我们塑造了最终的版本,并在我们一路上的决策过程中为我们提供了宝贵的直觉检查。
总的来说,在我们发布实验性功能后的几个月后,我们发布了组中智能布局的最终版本。在那段时间里,我们处理了反馈,修复了错误,并对其进行了一些重要的润色。希望这三篇博文能让你了解我们为什么花时间把事情做好。此外,我们希望您在实践中喜欢它!