为 Apple Watch 设计 Live Activities
Design Live Activities for Apple Watch
2024年6月10日
一句话判断
如果你的 App 已经支持了 iPhone Live Activities,watchOS 11 会自动把它带到 Apple Watch 上——但要做好,你需要理解 Smart Stack 的交互模型和 Watch 端独有的设计约束。
这场 Session 讲了什么
watchOS 11 把 Live Activities 带到了 Apple Watch 的 Smart Stack 里。Smart Stack 是 watchOS 10 引入的核心交互方式,用户不需要进入 App 列表,只需要在表盘上旋转 Digital Crown 就能看到一组按时间相关性排列的 Widget。watchOS 11 在此基础上加入了 Live Activities,当 iPhone 端启动一个 Live Activity 时,它会自动出现在 Apple Watch Smart Stack 的顶部,抬手就能看到。
两位 Apple Design Team 的设计师 Ed 和 Taylor 介绍了 Live Activities 在 Apple Watch 上的三种呈现形态:Smart Stack 中的 Widget 视图(抬手即看)、App 内的完整视图(点击 Widget 后进入)、以及正在使用其他 App 时弹出的 Compact View(底部的小型通知条)。这三种形态对应了不同的注意力层级——手腕放下时可以抬手查看完整信息,正在操作手表时则用紧凑视图做不打扰的提醒。
Session 的后半部分聚焦设计指南:Apple Watch 屏幕小,信息密度需要极度克制。官方建议只展示关键状态转换的信息——比如”航班还有多久降落”这类用户真正关心的变化,而不是事无巨细地堆数据。
值得深挖的点
自动生成 vs 手动适配:两种 Live Activity 实现
watchOS 11 提供了两种方式在 Apple Watch 上呈现 Live Activity。默认方案是系统自动将 iPhone Dynamic Island 的 Compact 状态资源重新组合,生成一个 Watch 端的 Live Activity。这个方案的优点是零成本——你不需要写任何新代码。但缺点也很明显:Compact 状态的信息量有限,排版也不一定适合 Watch 的圆形屏幕。
更好的做法是采用 Apple Watch 的 size class 做专门适配。你可以为 Watch 提供独立的 Widget 视图设计,展示更有用的信息和更精致的布局。Session 中对比了两种效果,差距肉眼可见——自动生成的版本信息模糊、布局空旷,而专门适配的版本信息精准、视觉紧凑。如果你的 Live Activity 是 App 的核心体验(比如运动追踪、外卖追踪),专门适配几乎是必须的。
交互层级的设计哲学
Apple 对 Watch 端 Live Activities 的交互层级做了细致的分类。这背后是一个关于”注意力管理”的设计原则:用户与手表的交互时间是秒级的,你不能假设用户会盯着屏幕看。所以:
- 抬手看到的 Widget 视图只放最关键的状态信息——“你的外卖还有 5 分钟到达”。
- Compact View 只提示”有更新”,用户主动上拉才看到更多。
- 控制按钮(比如暂停/继续)只适合需要实时操控的场景,如运动和计时器,且最多只放一个。
这套层级逻辑和 iPhone 上 Dynamic Island 的 expanded/compact 模式有相似之处,但 Apple Watch 的屏幕约束更强,需要更极端的取舍。一个常见的设计错误是在 Watch 端照搬 iPhone 的信息布局,结果文字过小、信息过载、用户根本来不及阅读。
代码片段
为 Apple Watch 适配 Live Activity Widget
// 在 Widget Extension 中,使用 Apple Watch 的 size class 做定制
@main
struct FoodDeliveryWidgetBundle: WidgetBundle {
var body: some Widget {
FoodDeliveryLiveActivity()
}
}
struct FoodDeliveryLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: FoodDeliveryAttributes.self) { context in
// Apple Watch 专用布局
LockScreenLiveActivityView(context: context)
} dynamicIsland: { context in
// iPhone Dynamic Island 布局(保持不变)
DynamicIsland {
// ...
} compactLeading: {
// ...
} compactTrailing: {
// ...
}
}
}
}
坑点:如果你没有提供 Watch 端专门适配,系统会自动用 Dynamic Island Compact 的资源生成一个基础版本。测试时务必在真机上对比两种效果,模拟器上的渲染和真实手表有差异。
只放关键状态信息
// 好的做法:只展示最关键的状态
struct LockScreenLiveActivityView: View {
let context: ActivityViewContext<FoodDeliveryAttributes>
var body: some View {
HStack {
// 状态图标 + 预计时间,仅此而已
Image(systemName: "bicycle")
.foregroundStyle(.green)
Text("约 \(context.state.estimatedMinutes) 分钟")
.font(.headline)
}
.padding()
}
}
// 不好的做法:堆砌太多信息
// Watch 屏幕上放不下地图、骑手姓名、订单号、商家信息这些内容
坑点:Watch 上 text size 不能太小,系统建议至少使用 .headline 或 .body 级别的字体。如果你的文字被截断,说明信息太多了,不是字体的问题。
Smart Stack 中保持可见
// watchOS 11 的 Smart Stack 在手腕放下后仍然保持可见
// 这意味着你的 Live Activity 信息需要在"静态"状态下也有意义
// 不要依赖动画来传达关键信息
struct TimerLiveActivityView: View {
let context: ActivityViewContext<TimerAttributes>
var body: some View {
VStack {
// 静态文本即可,不需要动画倒计时
Text(context.state.remainingTimeFormatted)
.font(.title2.monospacedDigit())
Label("专注模式", systemImage: "brain.head.profile")
}
}
}
最佳实践
如果你的 App 已经有 iPhone Live Activities,第一步是确认 watchOS 11 的自动生成效果是否可以接受。如果核心场景是信息展示类(如外卖追踪、航班状态),自动生成版本可能够用。但如果涉及控制操作(如运动暂停、音乐播放),或者你的品牌对视觉品质有要求,建议投入资源做 Watch 端专门适配。
适配时遵循”只放关键状态”原则:你的 Live Activity 应该回答”现在怎么样了”这个问题,而不是”所有信息是什么”。如果一个状态需要用户思考超过 2 秒才能理解,说明你的设计过于复杂。参考 Apple 提供的标准布局模板(详见去年 session “Design Widgets for the Smart Stack on Apple Watch”),这些模板已经针对不同信息密度做了优化。
还有什么值得关注
- Smart Stack 在 watchOS 11 新增了 Suggested Widgets——系统根据上下文自动添加/移除 Widget,比如下雨前 15 分钟自动出现天气 Widget。
- Live Activities 的 Compact View 是 watchOS 11 全新的交互形态,用户在其他 App 中也能看到你的 Live Activity 更新。
- 配合工程实现的 session 是 “Bring your Live Activity to Apple Watch”,里面有完整的代码接入指南。