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

Update your app for watchOS 10

元の動画を見る

ハイライト

watchOS 10 では Apple Watch App のナビゲーションが再設計され、垂直 TabView と NavigationSplitView が導入されました。Digital Crown のスクロールが主要な操作となり、.containerBackground() と新しいマテリアルシステムで glanceability(一目で把握しやすさ)が向上します。


主要内容

以前の Apple Watch では、ビューを切り替えるには画面上をスワイプする必要があり、手首を上げた状態では操作しづらく、もう一方の手を使うことも多かったです。watchOS のサイドナビゲーションも正確なタップが必要で、クラウンは主に地図のズームやリストのスクロールに使われていました。

watchOS 10 では Digital Crown がナビゲーションの中核になります。片手でクラウンを回すだけでビューを切り替えられ、手首を上げたままでも操作できます。Apple Watch チームは操作を再考しました。クラウンは片手の素早い操作に向いているのだから、主要なナビゲーション手段にすべきではないか、という発想です。

この新ナビゲーションを実現するには、2 つの SwiftUI コンポーネントが必要です。NavigationSplitViewTabView です。NavigationSplitView がサイドリストと詳細の関係を担い、TabView.verticalPage スタイルでビューを積み重ね、クラウンスクロールがその層で機能します。

同時に Apple は .containerBackground() modifier を導入し、各 tab を視覚的に区別しやすくしました。ユーザーは一目で今どのページにいるか分かります。新しいマテリアルシステム(Material.ultraThin)と組み合わせると、背景コンテンツを遮らずに重要情報を強調でき、glanceability が向上します。


詳細

watchOS 10 ではサイドナビゲーションが NavigationStack から NavigationSplitView にアップグレードされます(04:02)。

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

キーポイント:

  • NavigationSplitView はサイドリストと詳細の 2 部分構成
  • selection: $selectedBackyard で現在の選択項目をバインド
  • .listStyle(.carousel) でリスト項目を横スクロール。Apple Watch により適したジェスチャー
  • 詳細ビューは選択の有無で内容を切り替え
  • SDK アップグレード後、App は詳細ビューに直接入り(ユーザーが最も気にする内容)、Source List ボタンでリストに戻ります

垂直 TabView とクラウンスクロール

新しい垂直 TabView で Digital Crown がメインビューを直接切り替えます(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 は Gauge、List、カスタムビューなど任意の SwiftUI ビュー
  • 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
  • 第 1 引数は背景スタイル、for: .tabView で tab スコープを指定
  • 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. Digital Crown を主要ナビゲーションにする
  • やること:Apple Watch App をリファクタし、水平スワイプナビゲーションを垂直 TabView に置き換える
  • 価値:クラウンスクロールは片手操作で、手首を上げたままでも使える。画面上スワイプより人体工学に合う。watchOS 10 でデフォルトになり、ユーザーは全 App で期待する
  • 始め方:既存 TabView を .tabViewStyle(.verticalPage) に変更し、各 tab の navigationTitle を明確に。スクロール可能な tab は最後に配置
  1. 色で glanceability を高める
  • やること:各 tab やビューに独自の背景色を設定し、状態で色を変える
  • 価値:Apple Watch の画面は小さく、ユーザーは一瞥するだけ。色は文字より速い識別手段。データ異常時(水位低下など)は赤背景が数字より目立つ
  • 始め方:各 tab に .containerBackground() を設定し、計算プロパティでデータ状態に応じて色を変える。まず SDK を上げて新外観を得てから手動最適化
  1. マテリアルオーバーレイで重要情報を強調
  • やること:重要データに半透明マテリアル背景を重ねる
  • 価値:コンテンツ上に直接背景を描くと情報を遮る。マテリアルは背景をぼかしつつ前景を読みやすくする。スコアや状態表示など一目で見たいデータに適する
  • 始め方:数字や状態表示に .background(.ultraThinMaterial, in: .circle) を使い、.overlay() で隅に配置
  1. 高頻度操作を下部ツールバーへ
  • やること:最もよく使う操作を Toolbar の .bottomBar に置く
  • 価値:Apple Watch 画面下部はタップしやすく、.bottomBar はサイズをまたいで位置が一貫し、ユーザーが再学習不要
  • 始め方:既存ボタン配置を監査し、高頻度操作を ToolbarItemGroup(placement: .bottomBar) へ移動
  1. NavigationSplitView でナビゲーション構造を最適化
  • やることNavigationStackNavigationSplitView に置き換える
  • 価値:App 起動時に詳細ビューへ直行し、ナビゲーション手順を減らす。ユーザーが最も気にする内容を最初に置き、Source List ボタンでリストに戻る
  • 始め方Listselection バインドで従来のナビリストを置き換え、詳細は detail クロージャに配置

関連セッション

コメント

GitHub Issues · utterances