-
使用 SwiftUI 进行设计
探索 SwiftUI 设计方面的基础概念。了解系统组件如何让你的 App 在各平台上大放异彩,同时展现你的独特个性。
这个讲座最初作为“与 Apple 会面交流”活动“SwiftUI 基础知识:使用 SwiftUI 构建卓越的 App”的一部分讲授。请观看完整视频,以了解更多见解和相关讲座。资源
-
搜索此视频…
大家好。感谢各位的到来。 非常抱歉。在控制台这边。 能否把讲稿放大一点?我看不清。
感谢大家前来参加本次活动, 我们整个团队专门为各位和本次 活动准备了一份设计愿望清单。 我们非常激动能与大家分享 这个过程是如何付诸实践的。 希望你们能将我这些年来积累的一些经验 和设计流程,融入到你们自己的工作中。 那么,让我们开始吧。 我将从App 导航入手,第一步是为内容和功能 创建具体的板块。 这基本上就是我们惯用的开始方式。 在开始规划之前,我们需要明确究竟要构建什么。 导航这个话题虽然听起来有些枯燥, 但我个人非常喜欢。 所以接下来我们就从这里开始。 随后我会探讨布局,并介绍如何在屏幕上以 最佳方式呈现内容。
最后,我会深入讲解视觉设计。 正是这些组件和视觉 元素的有机结合,才能为你的App 带来清晰度与独特个性。
好的。正如我之前提到的, 我是从零开始设计这款App的, 而我做的第一件事就是思考App的导航,
确定App将包含的内容和功能, 这将为我提供一个良好的结构框架。 这样你就能有条理地 进行开发,并知道如何使用顶部栏和工具 栏等导航组件。
我首先进行了头脑风暴,列出了我和团队希望 这款App具备的所有功能和特性。
我们希望通过这款App来庆祝 目标的达成,并且欢迎所有创意。 当时我们正处于头脑风暴阶段。
设计师说:“就一分钟。” 随后,我进行了简化, 只保留了旅行愿望清单App的核心功能, 例如创建行程、添加照片、 搜索等;接着我退一步, 将相关功能分组,比如行程、活动、 进度以及庆祝已完成的行程。
这些分类代表了App的 三大核心板块,因此我将它们 命名为愿望清单、目标和搜索。
这就是我们的App。这就是它对你的意义。
无论你是从零开始,还是重新审视现有App, 进行这一练习都大有裨益。 我在开发者中心的工作坊中与开发者 们一起进行过一段时间,每次都让人大开眼界。 因此,我鼓励大家也尝试一下。 这有助于理清思路, 将头脑风暴中那些零散的想法 转化为相互关联的界面, 这样你就能准备好开始开发了。
接下来我会解释这一切如何 与 SwiftUI 相关联。 我知道这就是大家来这里的目的。 我马上就要在 iOS 部分讲到这一点了。 有两个组件支持App导航。 顶部栏和工具栏。
首先,我将向大家展示顶部栏的工作原理。
顶部栏显示App的顶级部分, 并在所有屏幕上始终可见。
在这个示例中, App给人的感觉可能比实际要复杂一些。 我们都见过这类App:功能越多, 顶部栏显示的选项就越多, 但其实没多少人喜欢这样。 这会让界面变得非常复杂。 所以我一直建议的一点是 :尽量减少标签页的数量。
这样既能保持界面简洁,又非常直观。 还能减少用户的决策负担。 所以每次打开App时, 我都能清楚地知道有哪些选项可用。
其次,保持标签栏的原生样式。 这在你们今天的宾果卡上吗?
正如你们所知, SwiftUI 组件(比如标签栏)自带 动画和无障碍支持等内置行为。 如果进行自定义,这些行为很容易丢失。
但别担心,App中还有 很多其他地方可以展现个性。 顶部栏只是不属于其中之一。
最后,确保标签栏使用清晰的图标和标签, 并与每个标签页内的内容相匹配。
“愿望清单”。它并没有通用的图标,对吧? 所以我选择了 一道彩虹,它既容易被识别, 又能体现人们渴望实现的愿望,对吧? 就像它充满希望一样。
另一方面,我们的目标是使用 一个更直观、更明确的图标, 它不仅与标签高度契合, 而且形状与其中的许多收藏品一致—— 我认为这是一个不错的细节处理。
只要遵循这些指南, 你的标签栏就能既高效又有效。
现在我要稍微岔开一下话题。 如果你想更深入地了解设计或标签栏,
请访问《人机界面指南》。 我们之前也提过这一点。 《人机界面指南》 汇集了所有 Apple 平台和技术的设计、 指导原则及最佳实践。
在向我们咨询之前, 这里是你寻求解答和建议的首选之地。 你可以在开发者网站的 “设计”板块中找到通往“海牙”的链接, 该板块还收录了极其宝贵的Apple设计资源。
“愿望清单”标签页的设计, 以及我迄今为止设计的几乎 所有其他App,都使用了该库中的原生组件。
在浏览并构建你的设计工具箱时, 不妨下载一下 SF Symbols App? 它堪称图标界的“苹果酒”。 其中收录了超过 7000 个符号, 你可以直接复制粘贴到设计稿或代码中。
这些就是我用于顶部栏的符号, 而且这绝不会是最后一次。 今天我还会提到它。 好了,回到正题。 顶部栏和工具栏都支持App导航。 但两者之间还是有区别的,对吧? 它们在不同的层级上发挥作用。 用户会使用顶部导航栏在App中进行跨模块移动。 我们刚才提到了顶级导航,对吧? 但当需要执行操作并进入特定板块时, 我们会使用工具栏。
工具栏包含不同的元素来支持导航。 首先,是当前视图的标题。 在这个屏幕上,你可以看到用户。
他们能清楚地知道自己。 他们身处“愿望清单”— —抱歉,是“愿望清单”板块, 并且对屏幕内容有一定的了解。 这就像是定下了基调。 然后,工具栏会显示 当前屏幕上最重要操作的控制按钮。 主要操作是创建行程。 因此,我在右上角放置了 一个用于执行此操作的控件。
工具栏的第三个元素是导航控件。 在这里的行程详情页面中, 我添加了返回按钮,允许用户返回上一级, 重新回到“愿望清单”。
为了便于用户快速浏览, 我尽量减少了操作数量。 与顶部栏采用相同的引导原则, 并通过选择用户熟悉的符号来确保含义清晰。
当项目过多时, 显然在这个示例 中,用户很难理解应该先做什么。 因此,为了解决这个问题,我只需将那些不 常用或更高级的操作归入 更多菜单中隐藏起来。
工具栏还能为关键操作提供醒目的样式。 这不仅增添了一抹亮色,还能
在设计App时立即形成视觉焦点。 请确保每个屏幕上仅对一项操作使用这种样式。 顶部 区域,我知道有很多突出的功能 我们可能想强调,但你知道, 如果所有内容都重要, 那就意味着没有什么是重要的。
所以,在这种情况下,没有旅行 计划的“旅行愿望清单”还算什么呢? 所以我希望将其突出显示。
关于工具栏,最后要说的一点是, 就像顶部栏一样, 最好保持原生样式。 我们一起说出来吧。
添加背景之类的额外元素其实会——你知道的—— 与你的内容产生冲突。 它会与功能、与过渡效果产生冲突。 稍后库尔特也会稍微谈谈这一点。
到目前为止,我主要 专注了App的结构以及用户如何 在其中导航。 现在是时候将内容引入界面, 并决定如何呈现它们了。
这就是我所说的布局。
我将向大家展示两个我常用的布局 模式:列表和集合。
这两种模式都极具灵活性, 你们完全可以选择其中一种, 但很快你们就会发现:根据想要 展示的内容以及用户需要对其进行的操作, 其中一种模式会比另一种更合适。
例如,当内容以文本为主时,我会使用列表。 没错。而且当需要展示多个项目时, 列表能帮助用户快速浏览。 这就是为什么这种布局非常适合旅行活动。
这里我使用了名为“edge to edge” 的样式,因为我有这个需求。 而当我需要对内容进行分类时, 我会使用group样式。 所以这只是细微的差别。 但inset 布局和圆角设计,确实能将列表中 不同类别的内容清晰区分开来。 因此,在App中我其实并不需要这种样式。 当你们下载并开始尝试时, 可能不会看到这个示例,但我还是想向 大家展示我是如何实现的,因为大家总 是对“何时使用‘边缘到边缘’样式、 何时使用‘内嵌’样式”感到困惑。 这就是我们的做法。
最后,为了帮助用户快速浏览和操作列表, 我使用了辅助元素和控件。 诸如图片和副标题之类的辅助元素, 能帮助用户更快地识别项目,而无需逐行阅读;
像这里的选择按钮这样的控件,则能让用户无 需切换到其他视图即可执行操作, 这在实际应用中非常常见。 有时App会变得非常复杂, 原因在于我们为了实现仅需 在列表视图中就能完成的几个操作, 却额外添加了视图。
有许多类型的控件可供添加, 以支持不同的功能。 因此,我建议大家去探索现有控件, 看看是否有机会简化布局。 这里有步进器、切换开关、 滑块等许多控件供大家尝试。
以上内容涵盖了列表, 它能帮助用户快速浏览文本。 但当目标是浏览照片、视频或产品时, 集合(Collections
)则更为合适。 SwiftUI 中的集合 本质上是由堆叠视图和滚动视图组成的, 它允许内容延伸至屏幕之外, 并引导用户通过滚动来探索其中的内容。
但在“愿望清单”标签页中,主要目标是浏览。 因此,我选择构建 一种包含多种集合变体的布局,
通过条带式呈现增强视觉效果, 营造出个性化且充满活力的氛围, 同时展示用户上传的照片。
请注意,使用集合时, 并非所有内容都能同时显示。 大部分内容都位于屏幕之外。 因此,为了建立正确的预期并鼓励用户滚动浏览, 我会确保有效添加标题和图片。 这意味着什么?
在这个示例中,你觉得这些图片是否增加了价值?
看起来是不是有点随意? 是的,非常随意。问题就在于, 有时我们会因此失去内容的公信力, 因为这些图片看起来毫无逻辑。 看起来不像经过精心策划的。
此外,我们还可以添加长度保持一致的标题。 否则,布局又会显得有些笨拙, 对齐也不够整齐。 这不仅会影响整个合集的观感, 还会影响垂直滚动时的体验— —尤其是当下方还有内容时。 现在一切看起来都有些摇摇晃晃。 因此,为合集内容制定一些规则, 能让整体呈现得更加整洁美观。
好的, SwiftUI 已经处理了我之前 在讲解中零星提到的许多设计原则,但诸如层级、 对齐和邻近性等概念, 都属于组件的一部分。 不过,我们也鼓励大家开始探索这些概念, 以此来创建自己的布局。 这正是视觉设计的重要组成部分。
因此,我们将利用文字颜色和图片来引导视线, 并展现你的个性。 到目前为止,我们一直侧重功能性,力求高效。 现在,让我们看看能否为设计增添更多个人魅力。 因此,我将专注模式用于视觉设计中影响最大 且最先显现的三个方面:文本样式、 语义色彩和一致性。
它们共同使App更令人愉悦、更易于理解, 这也是我非常喜欢的一点。 它们将为你提供指导,让你在App 发展过程中重复利用这些设计模式。
我将从文本样式开始讲起, 它们确立了样式层次结构。 它们——抱歉——它们 建立了层次结构,并确保在不同 屏幕尺寸和条件下都能保持可读性。 因此,我将使用系统文本样式, 这样你就能直接获得现成的层次结构。 但重要的是,你要根据 App中的具体用途选择合适的文本样式。 我会始终如一地使用它。 例如,标题三(Title 3)适用 于所有章节标题,比如夏日光辉。 这让每个屏幕看起来更均衡、更精致, 因为内容被划分为明确的板块; 当我看到某种 Textile 时, 只要知道它代表哪个层级, 就能准确理解内容的含义。
我依赖系统 Textile 的另 一个原因是动态类型—— 很多人会使用更大的 Textile, 因为需要提升阅读舒适度, 有时两者兼顾。 而使用动态类型时, 这些 Textiles 的名称保持不变, 但字号会始终更大。 所以请务必使用它。
如果你是字体爱好者, 你会注意到我似乎在整个App中都使用了 Apple SystemFont SF Pro, 但显然并非如此。 仅仅使用一种名为Pro的样式, 其中就包含多种变体, 这让我能够在不影响可读 性的前提下塑造App的个性。 我们追求一种更具运动感的氛围, 因此我在标题中使用扩展样式来强调, 而在某些叠加层中仅少量使用紧凑样式。
同样,我希望将选择保持在最小范围内, 这样既能让 UI 显得经过精心设计, 也能让App更容易维护和扩展。 然后我们回到 Textiles 的话题,就会想:哦, 什么时候该用扩展呢? 什么时候该用?现在我们有了大量的纺织风格、 大量的变体,还有——天哪—— 大量的字体。
所以之前在讲解集合时, 我提到图像承载了App视觉表现的大部分分量。 因此,语义色是UI的良好补充, 它们扮演着非常相似的角色,但更加具体,
即状态和反馈。 例如,我在整个App中都 使用“靛蓝”色,但在这里, 比如在已完成的任务中, 以及顶部栏中选中的标签页里,
我会避免将其或任何与靛蓝非常相似的颜色 用于装饰。 否则用户可能无法理解:这 到底是可交互的,还是…… “它有什么含义吗?” 我将这种颜色命名为“靛蓝”, 此前我们正在讨论语义化配色。 所以这并不是一种随处可见的颜色。 就是这样。是的,我是随机选的。
这些颜色由系统提供,每个原生——抱歉, 每个原生组件都有其专属的颜色。 所以我没有设置背景色。 我也没有设置分隔线颜色。 这些对我来说都是开箱即用的。 我唯一选择的就是这个强调色。
由于这些颜色会自动适应浅色和深色模式, 以及 Liquid Glass 效果和不同的屏幕环境, 因此最好不要再被自定义选项弄得手忙脚乱, 尤其是按钮和控件。
你们可能已经在App中注意到, 配色方案中还包含一种霓虹绿, 我只将其用于强调效果, 比如进度指示器和副标题。 再次强调,这是为了传达 含义并运用这些视觉隐喻。 因此,这种颜色并不具有语义含义。 你们在我们的设计套件中找不到它。 所以我确保它具有足够的对比度。 我已在各种不同的背景上进行了测试。 我还提供了一个用于提高对比度的数值。
因此,如果你决定使用非系统颜色, 只需确保遵循一些简单的规则。 就像这一条一样, 持续测试,并确保你的App依然富有表现力, 同时不影响可用性。
现在我快要结束了。 这意味着现在是确保一切 看起来最佳状态的好时机。 作为最后的润色, 我会回过头来确保所有元素对齐 且间距一致。
这会让设计显得更加精致,视觉上也更平衡。 它看起来很专业, 同时也支持人们如何接收信息并决定下一步行动。 如果大量组件像被塞进狭小 空间一样拥挤,会发生什么? 我们会感到压力,仿佛没有思考的空间或时间。 而当我们让界面呼吸得更舒畅一些时, 卓越的用户体验便开始显现—— 这正是为用户留出思考空间的关键。
因此在使用原生组件时, 我会特别注意以一致的方式使用它们, 确保在不同屏幕上保持统一。 我会避免让用户通过多种方式完成同一件事—— 这种情况有时确实会发生。 我们常常会因创建新屏幕而兴奋不已, 于是从零开始设计。 但这其中最棒的部分——不仅在于简化开发, 更在于用户将获得的体验— —在于重新利用这些组件。 用户知道在哪里见过这些组件。 他们了解这些组件的行为方式。 而且他们完全清楚系统对他们的预期。 例如,进度指示器 在这里使用了相同的强调色和相同的形状, 但尺寸略小一些。 它们出现在我熟悉的上下文中。是的。 它们……它们起什么作用? 这种一致性也有助于开发工作。 你需要构建的组件更少。
我在讲解集合时简要提到了图像, 但这当然也是视觉设计的一部分。 因此,在选择图片和插图时, 将它们并排摆放,观察它们在排版上是否协调。 细节程度和整体氛围, 然后你可以进行微调和调整, 让它们感觉像是同一个品牌的一部分。 让它们感觉像是属于同一个系列。 相信你的直觉。它们很可能没错。在哪个列表中? 例如,用户会上传自己的照片。 但再次强调,为了说明这一点, 我使用了图片向大家展示如何将其融入其中。 在代码中,你会能够访问这些图片。 这样你就能看出我们之前讨论过的模式。 所以我选择的是动态天空。 通常主体较小,或者与空间产生互动, 但核心理念是让用户界面比照片更突出——当然, 这需要你自行评估, 以确保App风格的统一性。
回过头来看,虽然我确实为这 款App的设计贡献了不少——
也许只是一点点——但实际上,很多设计 决策都是由你替我做出的。这确实是实话。
但这是事实。我真的很享受 与工程师们合作开发这款App的过程。 看到我设计的一切都能在代码 中得到非常贴切的实现, 这种感觉太棒了。 因此,我们非常兴奋能与大家分享这款App, 并希望你们能亲自体验一番。 希望你们能从中汲取一些技巧, App到自己的工作流程中, 从而减少一些不确定性— —你们知道的,这种不确定性有时会 在想要发挥创意时出现,比如在某个随机时刻; 或者说,这能为你们 在项目初期提供一个发挥创意的空间, 先做出决策、头脑风暴, 然后再开始编码。
所以,当你们重返工作时, 请先定义或评估App的结构及其导航逻辑。 有意识地使用组件。 这将帮助你做出清晰的决策。 这样,当你开始编码时, 你就完全清楚自己要往哪里走。 你完全清楚自己要构建什么。 没错,你将构建出一个更具目的性的App。 好的,那么请与 SwiftUI 携手合作。 让它承担繁重的工作, 然后尽你所能,为App注入个性、 创造力和人文关怀。
非常感谢大家。希望你们在构建 和体验这款App的过程中乐 在其中。 关于设计方面的内容就介绍到这里。 感谢大家的参与。 现在,我将话筒交还给 Leah。
-