watchOS 设计新趋势
What's new in watchOS design
2020年6月23日
一句话判断
watchOS 7 的设计更新不是表面功夫——新的全屏体验、改进的导航模式和 Complication 的新能力,都在重新定义”手腕上的应用应该长什么样”。
这场 Session 讲了什么
watchOS 7 带来了一系列设计层面的变化,Session 从设计原则出发,逐一介绍了新特性和最佳实践。最显著的变化是应用导航模式的演进——Apple 推出了更清晰的全屏体验和列表导航模式,替代了之前有些混乱的分页导航。
Complication(表盘复杂功能)获得了重大升级。watchOS 7 引入了新的 Complication 家族,支持展示更多类型的信息,包括圆形、矩形和额外的图形样式。更重要的是,一个应用现在可以提供多个 Complication,用户可以在同一个表盘上展示同一应用的不同信息维度。
Session 还讨论了 watchOS 应用的视觉设计原则:大字体、高对比度、触觉反馈优先。Apple 强调手表上的每一次交互都应该在 2-3 秒内完成——如果用户需要盯着屏幕超过 5 秒,说明你的设计出了问题。新的计时器、闹钟和地图等系统应用都是这些原则的范例。
值得深挖的点
多 Complication 策略
以前每个应用只能提供一个 Complication。watchOS 7 允许一个应用提供多个 Complication 家族成员,比如天气应用可以同时提供”当前温度”和”未来降雨概率”两个 Complication。这改变了应用与表盘的交互模式——用户可以在同一个 Infograph 表盘上同时看到温度和降雨概率,不需要切换表盘或打开应用。
从分页导航到列表导航
很多 watchOS 应用采用了分页(paging)导航——水平滑动切换页面。Apple 在 watchOS 7 中更推荐列表导航模式,特别是在信息层级超过两层时。列表导航的垂直滚动更符合手表的单手操作习惯,也更容易通过 Digital Crown 精确控制。Session 建议只在内容确实平行且不超过 3 个时才用分页模式。
代码片段
// watchOS 7 多 Complication 支持
import ClockKit
class ComplicationController: NSObject, CLKComplicationDataSource {
// 声明支持的 Complication 族
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
let descriptors = [
// 当前温度 Complication
CLKComplicationDescriptor(
identifier: "current_temp",
displayName: "当前温度",
supportedFamilies: CLKComplicationFamily.allCases
),
// 降雨概率 Complication
CLKComplicationDescriptor(
identifier: "rain_chance",
displayName: "降雨概率",
supportedFamilies: CLKComplicationFamily.allCases
),
// AQI 空气质量 Complication
CLKComplicationDescriptor(
identifier: "aqi",
displayName: "空气质量",
supportedFamilies: [.graphicCorner, .graphicCircular]
),
]
handler(descriptors)
}
func getCurrentTimelineEntry(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void
) {
// 根据 complication.identifier 返回对应数据
switch complication.identifier {
case "current_temp":
let entry = createTemperatureEntry(for: complication)
handler(entry)
case "rain_chance":
let entry = createRainEntry(for: complication)
handler(entry)
default:
handler(nil)
}
}
}
// watchOS 列表导航模式
import SwiftUI
struct WorkoutListView: View {
let workouts: [WorkoutType] = [
.running, .cycling, .swimming, .yoga, .hiking
]
var body: some View {
// 使用 List 进行垂直滚动导航
List(workouts) { workout in
NavigationLink(destination: WorkoutDetailView(workout: workout)) {
HStack {
Image(systemName: workout.icon)
.foregroundColor(workout.color)
Text(workout.name)
.font(.body)
}
}
.listRowBackground(Color.clear)
}
.listStyle(.carousel) // watchOS 特有的 carousel 样式
.navigationTitle("训练")
}
}
struct WorkoutDetailView: View {
let workout: WorkoutType
var body: some View {
VStack(alignment: .leading) {
Text(workout.name)
.font(.title3)
.fontWeight(.semibold)
Text(workout.description)
.font(.caption)
.foregroundColor(.secondary)
Button("开始") {
// 启动训练
}
.buttonStyle(.borderedProminent)
}
}
}
// SwiftUI 全屏 watchOS 体验
import SwiftUI
struct MetricsView: View {
@State private var heartRate: Double = 72
@State private var distance: Double = 0
var body: some View {
// 全屏沉浸式数据展示
ZStack {
Color.black.ignoresSafeArea()
VStack(spacing: 8) {
// 大字体显示核心数据
Text("\(Int(heartRate))")
.font(.system(size: 48, weight: .bold, design: .rounded))
.foregroundColor(.red)
.monospacedDigit()
Text("BPM")
.font(.caption2)
.foregroundColor(.secondary)
// 次要信息
HStack {
Label("\(String(format: "%.1f", distance))",
systemImage: "figure.walk")
Text("km")
}
.font(.caption)
.foregroundColor(.green)
}
}
}
}
最佳实践
- 每个手表界面只展示一个核心信息,次要信息用小字体或图标补充
- 使用 Digital Crown 作为主要交互输入——它是手表上最精确的输入方式
- Complication 的数据更新要高效,使用
CLKComplicationTimelineEntry的批量时间线条目减少更新频率 - 深色背景 + 高对比度文字是手表界面的黄金法则,避免浅色背景
- 测试时一定要在真表上操作,模拟器上的交互体验和真实手腕操作差别很大
还有什么值得关注
- watchOS 7 支持多表盘共享——用户可以将自定义的表盘配置分享给朋友,Complication 会自动适配
- 新的 tinted 表盘模式允许用户自定义 Complication 的强调色,你的 Complication 需要适配不同的配色方案
- Session 强调了手腕抬起的”瞥一眼”场景——用户从抬腕到看到信息应该在 1 秒内完成