WWDC Quick Look 💓 By SwiftGGTeam
Update your app for watchOS 10

Update your app for watchOS 10

观看原视频

Highlight

Apple 在 watchOS 10 中重新设计了 Apple Watch 应用导航,推出垂直 TabView 和 NavigationSplitView,让数字表冠滚动成为主要交互方式,同时通过 .containerBackground() 和新材质系统提升 glanceability(一目了然性)。


核心内容

以前在 Apple Watch 上切换视图,要用手在屏幕上滑动,手腕抬高时操作不便,还得腾出另一只手。watchOS 的侧边导航也需要精确点击,表冠基本只用于缩放地图和滚动列表。

watchOS 10 把数字表冠变成了核心导航工具。单手转动表冠就能在视图间切换,手腕抬着也能操作。这是 Apple Watch 团队重新思考交互的结果:既然表冠天生适合单手快速操作,为什么不把它变成主要导航方式?

要实现这个新导航,开发者需要两个 SwiftUI 组件:NavigationSplitViewTabViewNavigationSplitView 负责侧边列表与详情页的关系,TabView.verticalPage 样式堆叠视图,表冠滚动就在这层工作。

同时,Apple 引入了 .containerBackground() modifier,让每个 tab 在视觉上更独特,用户扫一眼就知道自己在哪个页面。配合新材质系统(Material.ultraThin),重要信息可以在不遮挡背景内容的前提下突出显示,提升 glanceability。


详细内容

watchOS 10 的侧边导航从 NavigationStack 升级为 NavigationSplitView04:02):

NavigationSplitView {
    List(backyardsData.backyards, selection: $selectedBackyard) { backyard in
        BackyardCell(backyard: backyard)
    }
    .listStyle(.carousel)
} detail: {
    if let selectedBackyard {
        BackyardView(backyard: selectedBackyard)
    } else {
        BackyardUnavailableView()
    }
}

关键点:

  • NavigationSplitView 有两个部分:侧边列表和详情页
  • selection: $selectedBackyard 绑定当前选中的项目
  • .listStyle(.carousel) 让列表项横向滚动,这是 Apple Watch 上更适合的手势
  • 详情页根据是否有选中项显示不同内容
  • 升级 SDK 后 App 直接进入详情视图(用户最关心的内容),通过 Source List 按钮返回列表

垂直 TabView 与表冠滚动

新的垂直 TabView 让数字表冠直接切换主视图(06:18):

TabView {
    TodayView()
        .navigationTitle("Today")
    HabitatGaugeView(level: $waterLevel, habitatType: .water, tintColor: .blue)
        .navigationTitle("Water")
    HabitatGaugeView(level: $foodLevel, habitatType: .food, tintColor: .green)
        .navigationTitle("Food")
    List {
        VisitorView()
            .navigationTitle("Visitors")
    }
}
.tabViewStyle(.verticalPage)

关键点:

  • .tabViewStyle(.verticalPage) 是关键,它让 tab 垂直堆叠,表冠滚动时自动切换
  • 每个 tab 可以是任意 SwiftUI 视图,包括 Gauge、List 或自定义视图
  • navigationTitle() 定义每个 tab 的标题,显示在顶部状态栏
  • 可滚动的 tab(如 List)放在最后,避免和表冠翻页冲突

底部工具栏

watchOS 10 新增 .bottomBar 工具栏位置,把操作按钮放在更容易点击的区域(08:37):

.toolbar {
    ToolbarItemGroup(placement: .bottomBar) {
        Spacer()
        Button {
            level = Int(min(100, Double(level) + 5))
        } label: {
            Label("Add", systemImage: "plus")
        }
    }
}

关键点:

  • .bottomBar 把工具栏放在屏幕底部,单手操作更稳定
  • Spacer() 把按钮推到右侧
  • 按钮可以直接修改状态,比如增加水位或食物
  • .bottomBar 跨屏幕尺寸保持一致的按钮位置

动态颜色计算与背景

根据状态动态改变颜色可以增强视觉反馈(09:48):

func backgroundColor(_ level: Int, for type: HabitatType) -> Color {
    let color: Color = type == .food ? .green : .blue
    return level < 40 ? .red : color
}

var waterColor: Color {
    backgroundColor(waterLevel, for: .water)
}

var foodColor: Color {
    backgroundColor(foodLevel, for: .food)
}

关键点:

  • backgroundColor() 函数根据级别和类型返回对应颜色
  • 级别低于 40 时返回红色,表示需要补充
  • 计算属性 waterColorfoodColor 自动响应状态变化
  • 这些颜色传入 .containerBackground() 实现动态背景

.containerBackground() 视觉区分

为了让每个 tab 一眼可识别,watchOS 10 引入 .containerBackground()10:10):

TabView {
    TodayView()
        .navigationTitle("Today")
        .containerBackground(Color.accentColor.gradient, for: .tabView)
    HabitatGaugeView(level: $waterLevel, habitatType: .water, tintColor: waterColor)
        .navigationTitle("Water")
        .containerBackground(waterColor.gradient, for: .tabView)
    HabitatGaugeView(level: $foodLevel, habitatType: .food, tintColor: foodColor)
        .navigationTitle("Food")
        .containerBackground(foodColor.gradient, for: .tabView)
    List {
        VisitorView()
            .navigationTitle("Visitors")
            .containerBackground(Color.accentColor.gradient, for: .tabView)
    }
}
.tabViewStyle(.verticalPage)
.environmentObject(backyard)
.navigationTitle(backyard.displayName)

关键点:

  • .containerBackground() 设置 tab 的背景,可以是纯色、渐变或任何 SwiftUI ShapeStyle
  • 第一个参数是背景样式,for: .tabView 指定应用范围
  • 不同 tab 用不同颜色,用户扫一眼就知道当前在哪个页面
  • .gradient 让颜色过渡更平滑,符合 Apple Watch 的设计语言
  • 颜色帮助用户在导航中建立位置感,不仅仅是装饰

新材质系统

watchOS 10 提供更细粒度的材质控制(11:38):

.foregroundStyle(.secondary)
.background(Material.ultraThin, in: RoundedRectangle(cornerRadius: 7))

关键点:

  • .foregroundStyle(.secondary) 让文字颜色变淡,适合次要信息
  • Material.ultraThin 是最轻的材质,背景内容透视度最高
  • in: RoundedRectangle(cornerRadius: 7) 限定材质应用范围
  • 材质会自动模糊背后的内容,保证前景可读

叠加材质可以在不遮挡背景的前提下突出重要信息(12:15):

.overlay(alignment: .topTrailing) {
    Text("\(backyard.visitorScore)")
        .frame(width: 25, height: 25)
        .foregroundStyle(.secondary)
        .background(.ultraThinMaterial, in: .circle)
        .padding(.top, 5)
}

关键点:

  • .overlay() 在现有视图上叠加一层内容
  • .ultraThinMaterial 是半透明材质,背景内容可见但模糊
  • .circle 创建圆形背景,适合显示数字或图标
  • .padding(.top) 调整位置,避免贴边

强制浅色模式可以在深色背景下确保文字可读(12:20):

.environment(\.colorScheme, .light)

关键点:

  • .environment(\.colorScheme, .light) 强制当前视图使用浅色模式
  • 当背景色很深时,浅色文字更清晰
  • 这个设置只会影响当前视图及其子视图

核心启发

  1. 把数字表冠变成主要导航方式
  • 做什么:重构你的 Apple Watch App,用垂直 TabView 替代水平滑动导航。
  • 为什么值得做:表冠滚动是单手操作,手腕抬着也能用,比在屏幕上滑动更符合人体工学。watchOS 10 把这个交互变成默认模式,用户会期待所有 App 都支持。
  • 怎么开始:把现有的 TabView 改成 .tabViewStyle(.verticalPage),确保每个 tab 的 navigationTitle 清晰可读。可滚动的 tab 放在最后。
  1. 用颜色区分提升 glanceability
  • 做什么:为每个 tab 或视图设置独特的背景色,并用状态驱动颜色变化。
  • 为什么值得做:Apple Watch 的屏幕小,用户只会扫一眼。颜色是最快的识别方式,比文字更快。当数据异常时(如水位过低),红色背景比数字提示更醒目。
  • 怎么开始:用 .containerBackground() 给每个 tab 设置不同颜色,通过计算属性根据数据状态动态变化。先升级 SDK,自动获得新外观,再逐步手动优化。
  1. 用材质叠加突出重要信息
  • 做什么:在关键数据上叠加半透明材质背景。
  • 为什么值得做:直接在内容上画背景会遮挡信息,材质既模糊背景又保证前景可读。适合展示评分、状态指示器等需要一眼看清的数据。
  • 怎么开始:用 .background(.ultraThinMaterial, in: .circle) 给数字或状态指示器加背景,用 .overlay() 定位到视图一角。
  1. 在底部工具栏放高频操作
  • 做什么:把用户最常用的操作放在 Toolbar 的 .bottomBar
  • 为什么值得做:Apple Watch 屏幕下方更容易点击,.bottomBar 跨屏幕尺寸保持一致的位置,用户不用重新适应。
  • 怎么开始:检查现有 App 的按钮位置,把高频操作移到 ToolbarItemGroup(placement: .bottomBar)
  1. 用 NavigationSplitView 优化导航结构
  • 做什么:把现有 NavigationStack 换成 NavigationSplitView
  • 为什么值得做:App 启动直接进入详情视图,减少导航步骤。用户最关心的内容放在第一位,通过 Source List 按钮返回列表。
  • 怎么开始:用 Listselection 绑定替代原来的导航列表,详情部分放在 detail 闭包中。

关联 Session

评论

GitHub Issues · utterances