WWDC Quick Look 💓 By SwiftGGTeam
What's new in UIKit

What's new in UIKit

元の動画を見る

ハイライト

iOS 17 の UIKit では Xcode Preview サポート、viewIsAppearing ライフサイクルコールバック、カスタム Trait システム、シンボルアニメーション効果、空状態設定 API、Collection View パフォーマンス約 2 倍向上など多数の改善が加わり、UIKit 開発が SwiftUI のような便利な体験に近づきました。

主要内容

Xcode Preview がついに UIKit に対応

UIKit 開発者は長年 SwiftUI のリアルタイムプレビューを羨ましく思っていました。iOS 17 でその壁が崩れました—#Preview マクロが UIViewController と UIView を直接サポートします。

プレビューでプロパティを設定しデータを投入でき、異なる設定の一括テストも可能です。SwiftUI の中間層も追加のラッパーコードも不要です。

viewIsAppearing: ちょうどいいタイミング

viewWillAppear は早すぎます—ビューはまだ階層に追加されておらず、trait collection も更新されておらず、ビューサイズも取得できません。viewDidAppear は遅すぎます—独立した CATransaction で実行されるため、変更はアニメーション終了後にしか表示されません。

iOS 17 では viewIsAppearing が追加され、viewWillAppear の後、viewDidAppear の前に呼び出されます。この時点でビューは階層に追加済み、レイアウト完了、trait collection も更新済みです。レイアウトコールバックのように繰り返し呼ばれることもなく、1 回だけ呼び出されます。

最も実用的なのは iOS 13 へのバックデプロイに対応していることです。

Trait システムのアップグレード

UITraitCollection は以前、システム定義の trait(ダークモード、size class など)のみ伝播していました。iOS 17 ではカスタム trait を定義し、独自のデータを trait システムに注入してビュー階層全体に自動伝播できます。

trait オーバーライド API とクロージャベースの変化リスナーも追加され、traitCollectionDidChange をオーバーライドするためのサブクラス化が不要になりました。カスタム UIKit trait は SwiftUI の environment key にブリッジでき、2 つのフレームワーク間のデータ連携がよりスムーズになります。

空状態を手作りする必要なし

すべてのアプリに空状態があります: 初回起動時のデータなし、ネットワーク切断、検索結果なし。以前はこれらすべてを自分で UI を組み立てる必要がありました。

UIContentUnavailableConfiguration.empty().loading().search() の 3 つのプリセットを提供します。view controller の contentUnavailableConfiguration プロパティに代入するだけで有効になります。UIHostingConfiguration で SwiftUI ビューをラップすることもできます。

updateContentUnavailableConfiguration(using:) メソッドと組み合わせ、データ変化時に setNeedsUpdateContentUnavailableConfiguration() を呼ぶと、空状態の表示/非表示が自動処理されます。

iPadOS 専用の改善

Stage Manager のウィンドウドラッグ領域が UINavigationBar 全体に拡大されました。UIWindowSceneDragInteraction で任意のビューにドラッグ機能を追加できます。

UISplitViewController は Stage Manager でよりスマートな列動作を獲得: サイドバーの自動非表示、狭い幅では overlay または displace モード、広い幅では tile モードに切り替え。

UIDocumentViewController がドキュメントアプリのベースクラスとなり、タイトルメニュー、共有、ドラッグ&ドロップ、キーボードショートカットを自動処理します。UIDocumentUINavigationItemRenameDelegate に準拠し、完全なリネーム体験を提供します。

Apple Pencil には monoline pen、fountain pen、watercolor、crayon の 4 つの新しいブラシが追加されました。PencilKit のデータモデルには新旧ブラシの互換性処理用の contentVersion プロパティが追加されました。

その他の強化

Collection View のパフォーマンスが大幅に向上: 1 万アイテムのソート反転は iOS 17 が iOS 16 比約 2 倍高速、半分のアイテム削除は約 3 倍高速です。アニメーションなしの更新ではさらに大きな向上があります。

Compositional Layout に uniformAcrossSiblings サイズが追加され、同一グループ内の self-sizing item を最大高さに揃えられます。

スプリングアニメーションパラメータは duration と bounce の 2 値に簡素化されました。UIView に対応するアニメーションメソッドが追加され、すべてのパラメータはオプションで、animate を呼ぶだけでシステムデフォルトのスプリング効果を使用できます。

ステータスバースタイルはコンテンツに応じて dark と light を自動切り替えし、左右分割で異なるスタイルにも対応します。手動でステータスバースタイルを制御するコードの多くを削除できます。

UIPageControl は分数進捗表示に対応し、UIPageControlTimerProgress と組み合わせて自動カルーセル、UIPageControlProgress と組み合わせて動画進捗を手動同期できます。

Palette Menu が iOS で利用可能になり、メニュー項目を水平配置—ツール選択、カラーピッカーなどのシーンに適しています。

詳細

UIViewController の Xcode Preview

01:31

class LibraryViewController: UIViewController {
    // ...
}

#Preview("Library") {
    let controller = LibraryViewController()
    controller.displayCuratedContent = true
    return controller
}

キーポイント:

  • #Preview マクロが UIViewController の返却を直接サポート
  • クロージャ内でプロパティを設定しデータを投入可能
  • コード変更後にプレビューが自動更新

UIView の Xcode Preview

01:48

class SlideshowView: UIView {
    // ...
}

#Preview("Memories") {
    let view = SlideshowView()
    view.title = "Memories"
    view.subtitle = "Highlights from the past year"
    view.images = ...
    return view
}

キーポイント:

  • view controller 不要、UIView を直接返却
  • 独立したビューコンポーネントの開発とデバッグに最適

空状態の設定

08:19

var config = UIContentUnavailableConfiguration.empty()

config.image = UIImage(systemName: "star.fill")
config.text = "No Favorites"
config.secondaryText =
    "Your favorite translations will appear here."

viewController.contentUnavailableConfiguration = config

キーポイント:

  • .empty() で空状態設定を作成
  • image、text、secondaryText を設定するだけ
  • view controller の contentUnavailableConfiguration に代入すると自動表示

SwiftUI で空状態をカスタマイズ

08:56

let config = UIHostingConfiguration {
    VStack {
        ProgressView(value: progress)
        Text("Downloading file...")
            .foregroundStyle(.secondary)
    }
}
viewController.contentUnavailableConfiguration = config

キーポイント:

  • UIHostingConfiguration で SwiftUI ビューをラップ
  • 複雑なカスタムレイアウトが必要な空状態に適する
  • UIKit の空状態 API とシームレスに統合

検索空状態

09:21

override func updateContentUnavailableConfiguration(
    using state: UIContentUnavailableConfigurationState
) {
    var config: UIContentUnavailableConfiguration?
    if searchResults.isEmpty {
        config = .search()
    }
    contentUnavailableConfiguration = config
}

// Update search results for query
searchResults = backingStore.results(for: query)
setNeedsUpdateContentUnavailableConfiguration()

キーポイント:

  • .search() は検索アイコン付きのプリセット空状態を提供
  • updateContentUnavailableConfiguration(using:) をオーバーライドしてデータ変化に応答
  • データ変化後に setNeedsUpdateContentUnavailableConfiguration() を呼び出して更新をトリガー

重要ポイント

  1. viewWillAppear の幾何関連コードを viewIsAppearing に移行

    • 何を作るか: ビューサイズや trait collection に依存する初期化ロジックを viewWillAppear から viewIsAppearing に移動
    • なぜ価値があるか: viewWillAppear 時はビューがまだレイアウトされておらずサイズが不正確; viewIsAppearing 時はすべて準備完了、iOS 13 へのバックデプロイも対応
    • 始め方: viewWillAppear 内で view.boundstraitCollection を読み取るコードを探し、viewIsAppearing に移行
  2. アプリ全体の空状態体験を統一

    • 何を作るか: アプリ内のすべての「データなし」「読み込み中」「検索結果なし」画面を UIContentUnavailableConfiguration に置き換え
    • なぜ価値があるか: 3 行のコードでシステム一貫の空状態スタイルを取得、表示/非表示の自動処理、SwiftUI カスタマイズもサポート
    • 始め方: view controller で updateContentUnavailableConfiguration(using:) をオーバーライドし、データ状態に応じて .empty().loading().search() を返す
  3. 重要な操作にシンボルアニメーションフィードバックを追加

    • 何を作るか: お気に入り、ダウンロード完了、Bluetooth 接続成功などの操作時に symbol アニメーションを再生
    • なぜ価値があるか: addSymbolEffect(.bounce) で 1 行のコードで明確な視覚的フィードバック、アラートより軽量
    • 始め方: 単純な成功状態に UIAlertController を使っている箇所を探し、symbol image + addSymbolEffect(.bounce) に置き換え
  4. Xcode Preview で UIKit コンポーネント開発を加速

    • 何を作るか: カスタム UIView と UIViewController に #Preview を追加
    • なぜ価値があるか: コンパイル&実行なしで UI を確認、レイアウト、色、フォント調整時に即時フィードバック
    • 始め方: ビューファイルの先頭に #Preview { YourViewController() } を追加し、必要なデータを設定
  5. Collection View の大量データ操作を最適化

    • 何を作るか: アプリ内の Collection View 大量データ更新が iOS 17 でのパフォーマンスを確認
    • なぜ価値があるか: iOS 17 の Collection View ソートは 2 倍高速、一括削除は 3 倍高速、アニメーションなし更新ではさらに向上
    • 始め方: Instruments の Time Profiler で既存コードを計測し、iOS 16 と iOS 17 を比較

関連セッション

コメント

GitHub Issues · utterances