View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • UIKitの新機能

    高度なメニューバーのサポート、監視の自動トラッキング、新しいUIアップデート方法、アニメーションの改善など、UIKitの最新のAPIを使用することでアプリをモダナイズできます。SwiftUIのシーンをUIKitアプリに追加する方法について説明し、SF Symbols、HDRカラーピッカーなども紹介します。

    関連する章

    • 0:00 - Introduction
    • 0:59 - New design system
    • 2:29 - Containers and adaptivity
    • 3:21 - The menu bar
    • 9:58 - Architectural 
improvements
    • 10:21 - Automatic observation tracking
    • 12:33 - New UI update method
    • 15:45 - Improvements to animations
    • 17:45 - Scene updates
    • 18:55 - HDR Color support
    • 20:38 - Swift notifications
    • 21:20 - Migrate to a scene-based life cycle
    • 22:40 - OpenURL support for file URLs
    • 23:17 - SF Symbols 7
    • 25:13 - Next steps

    リソース

    • Human Interface Guidelines
    • UIKit updates
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • 新しいデザインによるUIKitアプリの作成
    • 新しいデザインシステムの理解
    • iPadアプリのデザインの向上
    • SF Symbols 7の新機能
    • UIKitアプリの柔軟性の向上

    WWDC24

    • HDRを使用してアプリのダイナミックイメージ体験を向上

    WWDC23

    • アプリでシンボルをアニメーションする
    • アプリ内でのHDR画像のサポート

    WWDC21

    • iPad Appを次のレベルに
  • このビデオを検索

    こんにちは 「What’s new in UIKit」へようこそ UIKitチームでエンジニアリング マネージャーを務めている Dimaです iOSとiPadOSからtvOS、visionOS Mac Catalystまでのすべてにわたり UIKitは引き続きアプリの基盤ですが 今年はその機能が さらに強化されました まず UIKitにおける 新しいデザインシステムの サポートの概要を説明します 次に アプリのコンテンツを 様々なデバイスや画面の形状にスムーズに 適応させるための機能強化を確認します その後 メニューバー向けの 新しいUIKit APIを紹介します おなじみのmacOSの要素が iPadOSで利用可能になります UIKitのコアアーキテクチャの進歩について 詳細に説明しますが 途中で主な基礎知識もおさらいします 最後に フレームワークの全般的な 機能強化について より広範に解説します 新デザインシステムは システムの素材と コントロールの外観に活気をもたらします その中心となるのは 新しい素材であるLiquid Glassです 半透明で ダイナミックかつ精気にあふれ 鏡面ハイライトや屈折などの エフェクトを備えています バーや検索フィールドからアラート ポップオーバー、Split Viewに至るまで UIKitの標準コンポーネントのすべてが この新素材で刷新されています

    ナビゲーションの遷移は滑らかで 中断もできるようになり アプリの応答性が向上した印象を与えます

    ユーザーは アニメーションが終わるのを待たずに コンテンツの操作を開始できます

    皆さんのUIを 新しいデザインへと更新していただけるよう バックグラウンド拡張ビューなどの 新しいツールを導入しました このツールにより コンテンツがサイドバーの 大きなガラスの面の下に表示され 視覚的な連続性が維持されます

    カスタムコンポーネント用の ガラス素材もあります 新しいスクロールエッジエフェクトでは コンテンツがガラス面の下で スクロールする際 穏やかにフェードして バーボタンやその他のコントロールの 読みやすさを向上させます

    UIKitアプリの外観を更新するための 包括的なハンズオンガイドについては 「Build a UIKit app with the new design」をご覧ください 新しいデザイン自体の詳細については 「Get to know the new design system」をご覧ください 次に アプリのコンテンツを 様々なデバイスや画面の形状にスムーズに 適応させるための機能強化を確認します iOS 26ではUISplitViewControllerが インスペクタで高度にサポートされます インスペクタは 選択したコンテンツの 追加の詳細情報を提供します 例えば プレビューのインスペクタでは 写真とともに 付随的な列にメタデータが表示されます

    Split Viewコントローラの 分割線をドラッグして 列のサイズを変更することもできます ポインタの使用時 形状が変化して 列のサイズを どちらに変更できるかを示します コンテナビューコントローラの 機能強化の詳細を確認し レイアウト余白やセーフエリアなどの 一般的なレイアウトの概念の おさらいをするには 「Make your UIKit app more flexible」をご覧ください 次はメニューです iOS 26では macOSのメニューバーをiPadに導入します 上からスワイプすると アプリの全メニューが表示されます ハードウェアキーボードがない場合も OKです アプリの機能への迅速なアクセスを 提供する上で効果的な方法です

    メニューバーには画像 サブメニュー インラインセクション チェックマーク等全メニュー機能があります キーボードショートカットのないものも含め アプリの全コマンドを表示すべきです 使用できないコマンドも 無効にした状態で表示します それによりユーザーは そのアプリでできることをすべて把握できます

    アプリのメインメニューのカスタマイズには 引続きUIMenuBuilderを使用しますが iOS 26では さらに優れたメニューバーを構築できるよう UIKitに新しいAPIを導入しています まずは メインメニューのシステム構成です このAPIにより メインメニューに元々 用意されているすべてのシステムコマンドを カスタマイズできます 構成のためのAPIを使用すると 事前に作成およびローカライズされた インスペクタを切り替える 新しいコマンドなどの追加のメニュー要素を アプリで利用できるようになります どの項目を含めるか省略するかも 事前に宣言できます 詳細な構成を行い 要素の個々の グループのスタイルを設定することもでき 例えば アプリのニーズに応じた 検索コマンドの最適化などができます 最後に UIMenuBuilderブロックを 事前に提供してカスタム項目を追加すれば アプリとその共有Extensionの両方で 同じコードを使用して サポート対象の キーボードショートカットを定義できます 画面はメインメニューの システム構成の使用例です まず 構成オブジェクトを作成します 次に アプリのメインメニューに デフォルトで表示するコマンドを指定します 例えば システムの印刷コマンドの サポートを宣言します

    一部のデフォルトコマンドは除外します インスペクタパネルを切り替える 新しいコマンドなどです 構成により デフォルトのコマンドに 共通のスタイルを指定できます システム検索コマンドを 単一の検索項目に変換するなどです これは テキスト検索ではなく コンテンツ検索が重要である 写真アプリや音楽アプリで有効です 最後に メインメニューシステムの 構成を設定して システムが推奨要素の最初のセットで 構築されるようにします オプションで ビルドハンドラの提供もできます これは buildMenuWithBuilderの 代わりに呼び出されることになります ハンドラはUIMenuBuilderへの アクセスを提供しますが これは iOS 26でアップグレードされ より強力で便利なメソッド より高速なパフォーマンス より的確な診断を実現しています

    構成を設定すると メニューバーの再構築が トリガーされることに注意してください アプリの構成の設定は なるべく一度だけにして できる限り早めに実行すべきです application(_:didFinishLaunching WithOptions:)で設定するのはよい例です iOS/macOS 26のメニューバーには 追加の標準アクションと メニューが導入されます performCloseはCmd-Wにマッピングされ デフォルトでウインドウシーンを閉じますが Webブラウザのタブなど アプリ内の他のものを 閉じることもできます メニューコマンド「クリップボードから 新規作成」では ペーストアラートを トリガーすることなく ペーストボードの コンテンツからドキュメントを作成できます iOS 26で導入されたnewItemメニューは このコマンドの配置場所に最適です テキスト配置 サイドバー切り替え インスペクタ切り替えの標準アクションも カスタマイズで表示できるようになりました デフォルトでは キーを押さえたままだと キーボードショートカットは繰り返し 実行されますが UIKeyCommandの repeatBehaviorプロパティ設定で動作を カスタマイズできます

    このプロパティは validateCommandを 使って レスポンダごとにも設定できます これは 注意を要するアクションで 特に重要です メールを削除してしまう deleteキーを押すなどのアクションが 誤って繰り返し トリガーされないようにできます 場合によっては フォーカスされた項目や ウインドウシーンに基づいて メニューバーの一部で動的コンテンツの 表示が必要なことがあります 例えば Safariなどのブラウザアプリでは 履歴メニューに現在の ブラウズプロファイルの履歴を 表示する場合があります

    これをサポートするには 新しい フォーカスベースの遅延メニュー要素を使い レスポンダチェーンから要素を取得します メインメニューの構築時は UIDeferred MenuElement.usingFocusを作成し IDを付与して区別できるようにします そして それをメインメニューに挿入します

    遅延させた要素の実行が必要な場合 UiKitは その項目に対応できる レスポンダが見つかるまで レスポンダチェーンを探索します この例では BrowserViewControllerが providerの for DeferredMenuElementを上書きし 現在のプロファイルの履歴項目を提供します

    browserHistory要素の遅延要素の identifierをチェックし 履歴メニュー項目を読み込む プロバイダを返します フォーカスベースの遅延要素は 高コストな再構築をメインメニュー システムで実行することなく キーレスのコマンドで メニューバーを 最新の状態に保てる優れた方法です アプリのカスタム項目以外にも システムはいくつかのメニューエントリーを 自動で提供します 設定アプリの設定を開くための キーボードショートカットが アプリに提供されるほか ドキュメントベースのアプリでは 「最近使った項目」メニューに 最近使ったドキュメントが表示されます また ウインドウメニューに アプリで開いているシーンの全リストなどの タイル表示のためのコマンドも提供します ユーザーがシーンを区別できるよう 各シーンのタイトルを入力します 最後に メニューバーを構築する時に 覚えておくべきことがいくつかあります Storyboardで定義されたメニューバーが UIKitアプリでサポートされなくなりました アプリがStoryboardのメニューを 起動しないため プログラムで実装する必要があります

    また メニューバーが 常に存在するとは限らないため メニューバーがなくてもアプリの機能に アクセスできるようにする必要があります アプリに最適なメニューバーを 作成する方法について詳しくは 「Elevate the design of your iPad app」をご覧ください UIKitのメインメニューの概要については 「Take your iPad apps to the next level」をご確認ください Appleは UIKitを進化させ続けるために 最新のパターンのための新機能 ベストプラクティス SwiftUIの より高度な相互運用性を追加しています iOS 26も例外ではありません ここでは アーキテクチャにおける 興味深い新しい機能強化をご紹介します まず重要なのは UIKitでの Swift Observableオブジェクトの 組み込みのサポートです

    UIKitはSwift Observationを コア要素として統合します layoutSubviews()などの 更新のメソッドで 参照するすべての Observableを自動追跡し 依存関係を設定して 正しいビューを無効にします 手動でのsetNeedsLayout設定は 不要です これをiOS 18にバックデプロイするには UIObservationTrackingEnabledキーを Info.plistに追加します これは iOS 26ではデフォルトで有効です 監視の自動追跡の例を いくつか見てみましょう

    これは 未読メッセージを示す Uiラベルを含む メッセージリストの ビューコントローラです

    これをバックアップするObservableModel オブジェクトには2つプロパティがあります ステータスを表示するかどうかを制御する ブール値と ステータスの文字列です viewWillLayoutSubviews()で Observableモデルを使用し ラベルのアルファ値を更新して 表示/ 非表示を切り替え テキストを設定します 最初のレイアウトで UIKitはラベルを表示し 監視の自動追跡によって showStatusとstatusTextの 依存関係を記録します これらのプロパティに変更があると ビューは無効化されて viewWillLayoutSubviews()が 再実行され コード追加なしでラベルが常に同期されます もう1つ UIKitでのObservable オブジェクトの使用例をお見せします UICollectionViewのセルを 構成する際の監視の自動追跡のメリットが 明確に示されています アイコン タイトル サブタイトルを含む リストセルの各々を 監視可能な ListItemModelでバックアップします セルプロバイダコールバックの中で セルをキューから削除し モデルを取得して configurationUpdateHandlerを 割り当てます このハンドラは 監視の追跡をサポートするので UIKitは自動的に その中で使用するObservable オブジェクトとの依存関係を確立します

    ハンドラ内で 監視可能なリスト項目のモデルを使用して リスト内容の構成を入力し適用します これで完了です セルが可視状態の間に モデルのプロパティに変更があった場合 UIKitはハンドラを再実行し セルを更新します 特性と監視の自動追跡の追加により UIKitに これらの機能をサポートする汎用的な 更新のメソッドが備わりました

    UIViewとUIViewControllerの 両方で利用できる 新しいupdateProperties()メソッドを 導入します

    layoutSubviews()の直前で 実行されますが 独立しており レイアウトを強制することなく プロパティを無効化したり その逆を行ったりできるので 余分なパスを回避して よりきめ細かい更新を実行できます

    updateProperties()は layoutSubviews()に 取って替わるのではなく 補完します コンテンツの入力 スタイルの適用 動作の設定に使用できます

    読み込みを行うすべてのObservableを 自動追跡します setNeedsUpdateProperties()を 呼び出し 手動でトリガーすることもできます この新しいメソッドの 具体的な使用例を見てみましょう

    これは 監視可能な BadgeModelオブジェクトであり バッジビューに表示される カウントを格納します バーボタン項目のビューコントローラは BadgeModelでバックアップされます

    updateProperties()内でバーボタン 項目に 新しいバッジのAPIを使用し モデルから直接 カウントを取得します 監視可能なモデルオブジェクトが変更 されると updateProperties()が実行され バッジが更新されるようになりました

    ビューの構成に layoutSubviews()ではなく updateProperties()を使うと サイズ変更などの 関連のないイベントに コードが再実行されるのを防止して 不要な処理を減らし パフォーマンスを向上させることができます updateProperties()が 他の更新メソッドと どのように連係するかをより詳しく 説明するために UIKitの更新パスの仕組みを紹介します

    これは UiKitがビューを 画面に表示する前に更新する 仕組みを示すイラストです 最初はレイアウトパスです UIKitは ビューの階層を上から下へと進み 各ビューの特性を更新してから layoutSubviews()を呼び出します このパスで 他のビューに レイアウトが必要になると レイアウトパスは すべてのレイアウトが 完了するまで繰り返されます

    レイアウトが完了すると UIKitは ディスプレイパスの実行に移り 各ビューに対してdrawメソッドを呼び出し すべてのビューで表示が 必要なくなるまで パスを繰り返します 両方のパスが完了すると 次のフレームをレンダリングして 画面に表示できるようになります

    ここで 新しいupdateProperties() コールバックの出番です 上から下へのレイアウトパスでは UIKitはupdateProperties()を 特性を更新した直後 layoutSubviews()の直前で実行します layoutSubviews()は 2つの段階に 分けて考えることができます まずはプロパティの更新 その後に通常のレイアウトロジックです 特性のコレクションはupdateProperties ()の実行前に更新されるので 実行時に問題なく読み込めます また 常にlayoutSubviews()に先行 するため その中のレイアウトを無効にして レイアウトパスをその後すぐに実行できます

    新しい監視の追跡機能と updateProperties()メソッド補完のため UIKitでのアニメーションの動作を 改善しました

    説明を始める前に iOS 18以前での 手動アップデートの仕組みを確認します UIViewアニメーションクロージャではまず Observableオブジェクトに 新しい値が設定されてから そのオブジェクトに依存するビューで 必要に応じてレイアウトが呼び出されます 最初のステップで無効化が行われ 次のステップで更新が実行されて アニメーションが生成されるので 両方のステップが必要です プロパティのビューと依存関係を 手動で管理すると ミスが生じやすく 更新やアニメーションの数が多すぎ または少なすぎになる可能性があります iOS 26には UIView用アニメーションの 新しいオプション flushUpdatesがあります 有効にすると UIKitはアニメーションの 開始直前と終了後に 更新の保留を 適用するので layoutIfNeeded()の 呼び出しが不要になります flushUpdatesを機能させるには単に 状態変化の無効化を アニメーションクロージャの中に配置します では flushUpdatesの 使用方法をご紹介します まず flushUpdatesをオプションとして UIView animateに渡し 次にクロージャの中で Observableオブジェクトを変更します そのObservableオブジェクトを updateメソッドで使用しているビューでは 自動的に必要なアップデートが行われます flushUpdatesはObservableにより 発生するアニメーションに限定されません

    それを利用して 自動レイアウトの制約の変更を 自動的にアニメーション化した例が こちらです flushUpdatesクロージャで 既存の制約の1つに 新しい定数を設定し その他の制約を有効化および無効化します 依存しているビューは新しい位置に移動し 自動的にサイズ変更されます 次に 同じアプリ内でのSwiftUIとUIKitの 併用をどうシームレスにしたかを説明します 新しいデリゲートプロトコルによって UIKitの アプリでSwiftUIシーンが使えるようになり SwiftUIの段階的導入もサポートされ UIKitアプリがvisionOSで イマーシブ空間やボリュームも 活用できるようになりました

    例えば 瞑想アプリで 和風の庭園を表示する場合なら iPhoneとiPadでは標準的2Dウインドウに visionOSではイマーシブ空間にできます この空間を表現するため ルートにSwiftUIのシーンを使った 新しいUIHostingSceneDelegate プロトコルを実装します

    ホスティングシーンデリゲートの使い方は 他のシーンデリゲートと同じで 新しいシーンの接続時に UISceneConfigurationで デリゲートクラスの型を設定するだけです

    特定のSwiftUIのシーンを ホストのデリゲートから プログラムで要求するには その識別子を渡します

    この例では イマーシブな 和風庭園の空間を要求しています 最後に UIKitの一般的な 機能強化について説明します まず HDRレンダリング機能の 向上についてです iOS 26では HDRで画像だけでなく カラーにも同じ処理を施せるため ユーザーインターフェイスを際立たせたり 新しい体験を生み出したりできます

    UIColorではベースのSDRカラーと 露出値を指定できるようになり 輝度はディスプレイの性能に合わせて 自動的に調整されます ここでは赤のHDRカラーを作成し その露出をSDRのピーク白の 2.5倍に設定しています HDRカラーの選択も UIColorPickerViewControllerと UIColorWellで 有効化できるようになりました これを行うには 最大露出を アプリのレンダリング機能によって ガイドされた値に設定します ここではカラーピッカーの最大線形露出を SDRのピーク白の 2倍に設定します

    iOS 18では UIImageViewがHDRを SDRにインテリジェントにフォールバックして UIの重要なコンテンツを際立たせます iOS 26ではこの動作がビデオにも拡大され 独自のカスタムコンテンツも同様に 際立たせることができます 新しいUITraitHDRHeadroomUsage特性は HDRコンテンツをSDRにフォールバックさせる タイミングを監視するために使用します HDRの詳細を知る上で役立つビデオは 「Use HDR for dynamic image experiences in your app」と 「Support HDR images in your app」 です

    iOS 26のUIKitでは 今後 NSNotification.Name APIを利用して それぞれの通知が専用のNotification Center.Message型で表されます これによって オブザーバを登録したり イベントの詳細を取得したりするための 厳密に型指定された値が得られます これはキーボードが表示されたときの レイアウト調整の例です まずkeyboardWillShowという 通知タイプに登録してから ハンドラでアニメーションの継続時間と キーボードのフレームを メッセージから直接プルします 最後にその値を使って制約をアニメ化します ユーザー情報のルックアップや 手動のキャスティングは不要です UIKitは進歩を続けており リリースのたびに 新たなベストプラクティスを実現する 最新の強力なAPIが生まれています それらが採用されるのに合わせて 従来のメソッドは廃止されています

    UISceneを採用することで アプリは ポータブルになり柔軟性も高まるため UIApplicationを中心としたAPIの多くは 廃止されつつあります

    従来の UIApplicationDelegateコールバックと UIApplicationLaunchOptionKeysは すでに不要になり UIWindowのinit(windowScene:) イニシャライザだけが残っています その他のイニシャライザはみな廃止されます iOS 26以降のリリースでは 最新の SDKで開発されたUIKitアプリはみな UISceneのライフサイクルを利用するよう 求められ そうでないと起動しなくなります

    マルチウインドウアプリだけでなくどこでも UISceneのライフサイクルを採用します その方法の詳細について 紹介しているテクニカルノートが 「Migrating to the UIKit scene-based life cycle」です UIRequiresFullScreenから 移行するために役立つAPIなど アプリの柔軟性を最大限に高めるための 情報については 「Make your UIKit app more flexible」をご覧ください

    様々なドキュメントタイプを扱うアプリは 外部ビューアの起動が 必要になることがよくあります iOS 26では既存のopenURLメソッドが ファイルのURLを認めるようになったため アプリがネイティブにサポートしていない ドキュメントも配布できるようになりました そのファイル形式に デフォルトのアプリがある場合は それが自動的に起動されて URLが渡されます そうでない場合はfalseが返され 自分で フォールバックを処理する選択肢が出ます 例えば クイックルックプレビューの コントローラを使うなどです

    iOS 26では SF Symbolsが強化されました SF Symbols 7は シンボル描画機能を付加し まず 2つの新しい効果を実装します drawOffは消去エフェクトと同様に 描画 アニメーションでシンボルを非表示にします drawOnは「表示」のようなもので 描画によって非表示のシンボルを表示します

    シンボルは変数値用の新しいモードである Variable Drawに対応するようになりました このモードではこのインジケータのように 任意の値がパスに沿って描画されます またこれを自動的なシンボルコンテンツの 遷移に利用すれば 変数値による アニメーションを作成できます

    また「マジック置換」の遷移でも 特定のシンボルの間に特殊な 描画アニメーションを作成できます 例えば この円シンボルと塗りつぶしの チェックシンボルの間の遷移では 円が塗りつぶされ チェックシンボルが 描画されるようになります 新しい描画アニメーションは ボタンに 使用すると非常に便利なので UIKitに UIButtonにシンボルコンテンツの遷移を 簡単に導入できる 新APIが追加されます

    UIButton.Configurationで 新しい symbolContentTransitionプロパティを 使用して 置換などの シンボルコンテンツの遷移を指定できます 選択の状態が切り替わったなどで ボタンのシンボルが変更されると UIKitが遷移を実行します SF Symbols 7では 新しい カラーレンダリングモードのオプションなど その他の機能も導入されます アプリではシンボルの色付けに グラデーションを指定できます 単色の代わりに 自動生成された グラデーションを使用します

    描画とグラデーションを フルにカスタマイズする方法については 「What’s new in SF Symbols 7」を ご覧ください シンボルのエフェクトを取り入れる方法を 再確認するには 「Animate symbols in your app」を ご覧ください

    次のステップとして まずは iOS 26 SDKを使用して アプリをコンパイルしましょう 新デザインでのアプリの応答性を確認し 新しい美観を活かせるよう UIとスタイルを洗練させましょう 柔軟なレイアウトに対応できるよう UISplitViewControllerや UITabBarControllerなどの 標準コンテナを使いましょう 新しいメニューAPIを使用して アプリのメニューを実装しましょう updatePropertiesメソッドと 監視の追跡を導入して コードを効率化し パフォーマンスを向上させましょう ご視聴ありがとうございました ご紹介した機能強化を 皆さんがどのように活用して パワフルで使いやすいアプリを 実現するか 楽しみにしています

    • 4:56 - Main menu system configuration

      // Main menu system configuration
      
      var config = UIMainMenuSystem.Configuration()
      
      // Declare support for default commands, like printing
      config.printingPreference = .included
      
      // Opt out of default commands, like inspector
      config.inspectorPreference = .removed
      
      // Configure the Find commands to be a single "Search" element
      config.findingConfiguration.style = .search
    • 5:39 - Main menu system build configuration

      // Main menu system configuration
      
      // Have the main menu system build using this configuration, and make custom additions.
      // Call this early, e.g. in application(_:didFinishLaunchingWithOptions:), and call it once
      UIMainMenuSystem.shared.setBuildConfiguration(config) { builder in
          builder.insertElements([...], afterCommand: #selector(copy(_:)))
      
          let deleteKeyCommand = UIKeyCommand(...)
          builder.replace(command: #selector(delete(_:)), withElements: [deleteKeyCommand])
      }
    • 7:01 - Keyboard shortcut repeatability

      // Keyboard shortcut repeatability
      
      let keyCommand = UIKeyCommand(...)
      keyCommand.repeatBehavior = .nonRepeatable
    • 7:43 - Focus-based deferred menu elements (App Delegate)

      // Focus-based deferred menu elements
      
      extension UIDeferredMenuElement.Identifier {
          static let browserHistory: Self = .init(rawValue: "com.example.deferred-element.history")
      }
      
      // Create a focus-based deferred element that will display browser history
      let historyDeferredElement = UIDeferredMenuElement.usingFocus(
          identifier: .browserHistory,
          shouldCacheItems: false
      )
      
      // Insert it into the app’s custom History menu when building the main menu
      builder.insertElements([historyDeferredElement], atEndOfMenu: .history)
    • 8:06 - Focus-based deferred menu elements (View Controller)

      // Focus-based deferred menu elements
      
      class BrowserViewController: UIViewController {
      
          // ...
        
          override func provider(
              for deferredElement: UIDeferredMenuElement
          ) -> UIDeferredMenuElement.Provider? {
              if deferredElement.identifier == .browserHistory {
                  return UIDeferredMenuElement.Provider { completion in
                      let browserHistoryMenuElements = profile.browserHistoryElements()
                      completion(browserHistoryMenuElements)
                  }
              }
              return nil
          }
      }
    • 10:54 - Using an Observable object and automatic observation tracking

      // Using an Observable object and automatic observation tracking
      
      @Observable class UnreadMessagesModel {
          var showStatus: Bool
          var statusText: String
      }
      
      class MessageListViewController: UIViewController {
          var unreadMessagesModel: UnreadMessagesModel
      
          var statusLabel: UILabel
          
          override func viewWillLayoutSubviews() {
              super.viewWillLayoutSubviews()
      
              statusLabel.alpha = unreadMessagesModel.showStatus ? 1.0 : 0.0
              statusLabel.text = unreadMessagesModel.statusText
          }
      }
    • 11:48 - Configuring a UICollectionView cell with automatic observation tracking

      // Configuring a UICollectionView cell with automatic observation tracking
      
      @Observable class ListItemModel {
          var icon: UIImage
          var title: String
          var subtitle: String
      }
      
      func collectionView(
          _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
      ) -> UICollectionViewCell {
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
          let listItemModel = listItemModel(for: indexPath)
          cell.configurationUpdateHandler = { cell, state in
              var content = UIListContentConfiguration.subtitleCell()
              content.image = listItemModel.icon
              content.text = listItemModel.title
              content.secondaryText = listItemModel.subtitle
              cell.contentConfiguration = content
          }
          return cell
      }
    • 13:27 - Using automatic observation tracking and updateProperties()

      // Using automatic observation tracking and updateProperties()
      
      @Observable class BadgeModel {
         var badgeCount: Int?
      }
      
      class MyViewController: UIViewController {
         var model: BadgeModel
         let folderButton: UIBarButtonItem
      
          override func updateProperties() {
              super.updateProperties()
      
              if let badgeCount = model.badgeCount {
                  folderButton.badge = .count(badgeCount)
              } else {
                  folderButton.badge = nil
              }
         }
      }
    • 16:57 - Using the flushUpdates animation option to automatically animate updates

      // Using the flushUpdates animation option to automatically animate updates
      
      // Automatically animate changes with Observable objects
      UIView.animate(options: .flushUpdates) {
          model.badgeColor = .red
      }
    • 17:23 - Automatically animate changes to Auto Layout constraints with flushUpdates

      // Automatically animate changes to Auto Layout constraints
      UIView.animate(options: .flushUpdates) {
          // Change the constant of a NSLayoutConstraint
          topSpacingConstraint.constant = 20
          
          // Change which constraints are active
          leadingEdgeConstraint.isActive = false
          trailingEdgeConstraint.isActive = true
      }
    • 18:07 - Setting up a UIHostingSceneDelegate

      // Setting up a UIHostingSceneDelegate
      
      import UIKit
      import SwiftUI
      
      class ZenGardenSceneDelegate: UIResponder, UIHostingSceneDelegate {
          static var rootScene: some Scene {
              WindowGroup(id: "zengarden") {
                  ZenGardenView()
              }
      
              #if os(visionOS)
              ImmersiveSpace(id: "zengardenspace") {
                  ZenGardenSpace()
              }
              .immersionStyle(selection: .constant(.full),
                              in: .mixed, .progressive, .full)
              #endif 
          }
      }
    • 18:28 - Using a UIHostingSceneDelegate

      // Using a UIHostingSceneDelegate 
      
      func application(_ application: UIApplication,
          configurationForConnecting connectingSceneSession: UISceneSession,
          options: UIScene.ConnectionOptions) -> UISceneConfiguration {
      
          let configuration = UISceneConfiguration(name: "Zen Garden Scene",
                                                   sessionRole: connectingSceneSession.role)
      
          configuration.delegateClass = ZenGardenSceneDelegate.self
          return configuration
      }
    • 18:41 - Requesting a scene

      // Requesting a scene
      
      func openZenGardenSpace() {
          let request = UISceneSessionActivationRequest(
              hostingDelegateClass: ZenGardenSceneDelegate.self,
              id: “zengardenspace")!
        
          UIApplication.shared.activateSceneSession(for: request)
      }
    • 19:18 - HDR color support

      // Create an HDR red relative to a 2.5x peak white
      let hdrRed = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0, linearExposure: 2.5)
    • 19:50 - HDR color picking

      // Support picking HDR colors relative to a 
      // maximum peak white of 2x
      colorPickerController.maximumLinearExposure = 2.0
    • 20:06 - Mixing SDR and HDR content

      // Mixing SDR and HDR content
      
      registerForTraitChanges([UITraitHDRHeadroomUsageLimit.self]) { traitEnvironment, previousTraitCollection in
          let currentHeadroomLimit = traitEnvironment.traitCollection.hdrHeadroomUsageLimit
          // Update HDR usage based on currentHeadroomLimit’s value
      }
    • 20:54 - Adopting Swift notifications

      // Adopting Swift notifications
      
      override func viewDidLoad() {
          super.viewDidLoad()
      
          let keyboardObserver = NotificationCenter.default.addObserver(
              of: UIScreen.self
              for: .keyboardWillShow
          ) { message in
              UIView.animate(
                  withDuration: message.animationDuration, delay: 0, options: .flushUpdates
              ) {
                  // Use message.endFrame to animate the layout of views with the keyboard
                  let keyboardOverlap = view.bounds.maxY - message.endFrame.minY
                  bottomConstraint.constant = keyboardOverlap
              }
          }
      }
    • 24:26 - Using a symbol content transition to automatically animate symbol updates

      // Using a symbol content transition to automatically animate symbol updates
      
      var configuration = UIButton.Configuration.plain()
      configuration.symbolContentTransition = UISymbolContentTransition(.replace)

Developer Footer

  • ビデオ
  • WWDC25
  • UIKitの新機能
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン