View in English

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

クイックリンク

5 クイックリンク

ビデオ

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

その他のビデオ

  • 概要
  • トランスクリプト
  • コード
  • SwiftUIによるvisionOSのシーンの設定

    visionOSアプリのウインドウ、ボリューム、イマーシブ空間を強化する、エキサイティングな新しいAPIを紹介します。再起動やロックされた場合にシーンの動作を微調整したり、クリッピングマージンやスナップ機能を使ってボリュームを周囲に適応させたりすることが可能です。イマーシブなコンテンツをMacからVision Proにストリーミングすることもできます。ボリュームとイマーシブ空間を活用して、UIKitベースの既存のアプリを向上させましょう。

    関連する章

    • 0:00 - イントロダクション
    • 2:11 - 起動とロック
    • 8:15 - ボリュメトリックの機能強化
    • 15:58 - イマーシブ空間
    • 22:16 - シーンブリッジング
    • 24:01 - 次のステップ

    リソース

    • Adopting best practices for persistent UI
    • Canyon Crosser: Building a volumetric hike-planning app
    • Petite Asteroids: Building a volumetric visionOS game
    • Tracking accessories in volumetric windows
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • イマーシブなアプリを作成するためのMetalレンダリングの新機能
    • ウィジェットの新機能
    • SwiftUIとRealityKitの連係
  • このビデオを検索

    こんにちは Miguelです SwiftUIチームのエンジニアです このビデオでは visionOS 26に追加されたシーンの 素晴らしい新機能を いくつかご紹介します そして 私たち自身のシーンを どのように演出するかも学ぶかもしれません

    visionOSの3つのシーンタイプは ウインドウ ボリューム イマーシブ空間です アプリでは この3つを組み合わせることで 独自の魅力的な体験を創出できます

    本日は 3つのタイプすべてに適用される 新しいAPIと ボリュームとイマーシブ空間に重点を置いた いくつかのAPIについて説明します 友人のMaks、Amanda、Trevorが BOTanistの 魅力的な改良に取り組んでいます 空中庭園でロボットが美しい植物を 育てるのを手伝うゲームです

    私自身は シーンの構築や装飾をとおして アプリに取り組んできました ロボット君がシェイクスピアの キャラクターに生命を吹き込み 演技の世界に挑戦するのを 手助けしてきました

    アプリを開くと ステージ選択画面が 表示されます 新しいステージを作成します

    これで BOTanistを動かして シーンを設定できます ステージのいたるところに移動できます

    これで ロボット君が お気に入りの演劇を再現できます まるで「ロボとジュリエット」です

    新しいシーンAPIでアプリを 改善する方法を見てみましょう visionOS 26の新しいシーンAPIです

    最初に 新しいライフサイクルAPIについて 説明します ウインドウを起動して ルームに 固定するときの動作を定義します

    次に 新しいボリュメトリックの 機能強化について紹介します ユーザーの環境に合わせて調整できます

    そして RemoteImmersiveSpaceを 追加して macOSアプリから Apple Vision Proの シーンをプレビューします

    既存のUIKitアプリに対しては 新しいシーンブリッジAPIを使って これらの驚くべき立体的で没入感のある 体験を追加して締めくくります

    最初に 起動と固定について説明します

    visionOS 26では いくつかの macOS ライフサイクルAPIが導入されました これは非常に便利です シーンの復元とアプリの起動を 管理するAPIについて説明します 固有のウインドウを作成する APIについても説明します

    visionOS 26では ウィンドウやボリューム さらには 新しいウィジェットを特定の部屋に固定して 物理的な環境に保持できるようになりました

    これにより バーチャルコンテンツは その空間により存在感を持つようになります これらの固定されたウインドウは 使用された部屋に結び付けられます

    後でその部屋に戻ると ウインドウが再び表示されます

    固定機能によるシーン復元は 素晴らしいです すべてのウインドウを残しておき いつでも戻ってくることができます

    一般的に ユーザーはすべてのウィンドウを 固定できることを期待し システムがそれを復元することを望みます そのため ほとんどのシーンで復元を優先してください システムが自動的にこれを行います

    ただし いくつかのウィンドウは この方法で保持するのが 適切でない場合もあります

    ウェルカム画面や 特定のアプリ状態に結びついた ツールウィンドウ ログインプロンプトのような 一時的な要素では シーン復元を無効にすることを 検討してください

    アプリにイマーシブモードを追加したので お気に入りのロボットの動きを 十分に楽しむことができます ツールバーは 前方の独立した ツールウインドウに分離され イマーシブな状態でも 簡単に ステージコントロールにアクセスできます

    イマーシブ空間は復元されないことに 注意してください

    したがって この部屋に戻ってきたとき イマーシブ空間は復元されません

    ただし 誰かがツールウィンドウを 固定していた場合 単独で 何もない状態で 表示されることになります

    この予期しない状態を回避するには restorationBehavior(.disabled) 修飾子を WindowGroupに追加します これによりツールウィンドウが 復元および固定されなくなります

    これで 後でこの部屋に戻ったときに 余分なウィンドウは戻りません

    アプリを起動すると 最初のウィンドウが 表示され 新しいスタートとなります

    UIKitでは 新しい destructionConditions APIの .systemDisconnectionプロパティを 使用してUIシーンの復元を無効にできます 詳しくはドキュメントをご覧ください

    場合によっては アプリが開始するシーンを 動的に変更することで メリットが得られることがあります

    例えば アプリの初回起動時に ステージ選択の前に 挨拶するウェルカムウィンドウを 追加したいと考えています

    アプリの状態に基づいて 起動時に表示する ウインドウをカスタマイズするには defaultLaunchBehavior修飾子を 使用します

    ここではアプリの初回起動時に ウェルカムウィンドウを 表示するように優先します

    そのウィンドウが表示されたら 値をオフに切り替えることができます もうそのウィンドウを表示する 必要はありません

    選択した起動ウインドウの役割は Info.plistの Application Scene Manifestの 希望するデフォルトシーンセッションの役割 プロパティと一致している必要があります

    つまりデフォルトのシーンセッションの 役割をウィンドウに設定すると アプリ起動時にシステムが 通常のウィンドウシーンのみを考慮します

    その場合defaultLaunchBehaviorで 優先しようとしても ボリュームは無視されます そのため 希望するシーンを そのセッションの役割と一致させてください

    defaultLaunchBehavior修飾子には もう一つ便利な機能があります

    部屋に戻ったときにツールパネルが 再表示されないようにしたいことと それを修正するために restorationBehaviorを 使えることについて話しました こちらでも似たような問題があります

    今のところ Crownを押して イマーシブ空間を解除し ツールウィンドウを閉じても

    アプリを再起動すると このウィンドウが再表示されます

    これにより 復元機能がある場合と同じような 予期しない状態になります

    代わりに ステージ作成ウィンドウから始めて 安全な状態でアプリを再開したいです

    これを行うにはdefaultLaunchBehavior (.suppressed)修飾子を ツールウインドウに追加します これにより ホームビューから アプリを再起動するときに このウィンドウを再表示しないように システムに指示します

    一般的に 予期しない状態に陥るのを避けるために セカンダリーシーンには defaultLaunchBehavior (.suppressed)を使用します

    UIKitではUISceneの destructionConditionsに userInitiatedDismissalオプションを 追加することで 同じ動作を実現できます

    visionOS 26では 独自のウィンドウの 作成もサポートしています

    これらは複製できないウインドウです 一度に1つの一意のインスタンスしか 存在できません

    Macと同様 WindowGroupではなく Window APIを使用して 宣言します

    ゲームウィンドウやビデオ通話のような 重要なインターフェースの重複を 防ぐためにこれらを使用してください

    また 1つ以上のインスタンスを 必要としない 補助的な機能を提供するために 使用してください

    ウェルカムウインドウには 複数のインスタンスは必要ありません そのため 独自のウインドウに置き換えます

    ただし メインステージのボリュームは 複数のステージを同時に作成できるように WindowGroupとして保持します

    すばらしい アプリのライフサイクルは これまでで最高です 固定時やアプリ起動時に表示される ウィンドウをカスタマイズしました そして 必要に応じてウィンドウを 独自に保つようにしました

    visionOS 26には ボリュームをさらに深めるための 多くの新しい強化機能があります

    新しい平面へのスナップ機能 表示機能の強化 および Clipping Margins API について話します

    では 早速始めましょう

    visionOS 26の新機能では ウィンドウやボリュームを 物理的環境にスナップできます ウィンドウを表面に近づけるだけで スナップできます 復元可能なウインドウの場合 これでウィンドウを固定して保持できます

    ウィンドウの背面を 壁のような垂直面にスナップできます ボリュームの底面を床やテーブルのような 水平面にスナップすることもできます

    visionOS 26の新機能のウィジェットは どちらの種類にもスナップできます

    visionOSアプリにウィジェットを 追加する方法について詳しくは 「What’s new in widgets」を ご参照ください

    ウィンドウやボリュームでは スナッピングイベントに関する 情報も取得できます

    アプリでは ボリュームをテーブルにスナップして 水平に固定できます

    これは第一歩ですが 空間におけるステージを より存在感のあるものにしたいと思います ボリュームがテーブルにスナップされたとき ロボットを直接テーブルに 立たせたいと思います

    スナッブ状態に関する情報を取得するには 新しい SurfaceSnappingInfo APIを使います

    このAPIは ウィンドウの一般的な スナップ状態を判断するための 簡単なisSnappedプロパティを 提供します

    より高度なユースケースでは スナップサーフェスの ARKit分類を取得できます この詳細レベルには ユーザーの許可が必要です その方法を説明します

    詳細なスナップサーフェス情報を 有効にするには まず Application Wants Detailed Surface InfoキーをYESに設定し Privacy World-Sensing Usage-Descriptionキーには 許可を求める際に表示する 説明を設定する必要があります

    これら2つのキーは アプリのInfo.plistで設定できます

    それが終わったらコードに取り掛かれます

    ここで 環境からsurfaceSnappingInfoを 取得します

    onChangeの中で シーンが現在 スナップされているかどうかを確認します そしてスナップ面の分類に アクセスする権限があるかを確認します

    authorizationStatusを確認ことで 必要に応じて 自動的に許可を求めます

    ここで テーブルにスナップされたとき ステージの下のプラットフォームを 隠したとします これを管理するために状態変数を使用します

    これらの変更により ボリュームをテーブルにスナップさせ ロボットが自分の環境で 存分に動作できます 素晴らしいですね

    また テーブルの周りを歩くと邪魔になる 壁が隠れるようにしたので 常にボリュームの中を見ることができます

    これはonVolumeViewpointChange 修飾子を使用して シーンの視点の変化に反応することで 行いました

    OwenがどのようにBOTanistに 追加したかは WWDC24の「Dive deep into volumes and immersive spaces」で 詳しくご確認ください

    また ステージの周りに 新しい小道具を配置できるようにしたいです ボリュームのツールバーに様々な小道具を 追加できるポップオーバーを追加できます

    いいですねようやく『The Tragedy of King Gear』を再現できます

    以前は 表示は Windowsでのみ サポートされていました

    visionOS 2.4で ネストされた表示の サポートが追加され シートから表示されるポップオーバーや オーナメントから表示される コンテキスト メニューなどが可能になりました

    visionOS 26では プレゼンテーションに まったく新しいソースが加わりました これで ボリューム内や ボリュームのオーナメントから RealityViewsへのアタッチメント またはRealityKitの PresentationComponentを使用して 直接プレゼンテーションができます

    アタッチメントと PresentationComponentを使った RealityKitでのプレゼンテーションについて 詳しくは 「Better Together: SwiftUI and RealityKit」をご参照ください

    これは 小さなサブセットに限定されません すべての表示タイプが利用可能です メニュー ツールチップ ポップオーバー シート アラート 確認ダイアログなどです

    これらのプレゼンテーションをSwiftUIで 作成する方法については ドキュメントを確認してください

    これらのプレゼンテーションはすべて 3Dコンテンツによって 隠されても見えるように 特別な視覚処理が施されています

    デフォルトでは 遮るコンテンツと さりげなくブレンドします

    ただし これは遮るコンテンツを 目立って突破するか その背後に隠れるように カスタマイズできます

    これをカスタマイズするには subtle prominent none オプションを使用します

    これらのオプションは presentationBreakthroughEffect 修飾子を使って適用できます

    プレゼンテーション以外の要素には breakthroughEffect修飾子を使用して 同じ効果を得ることができます

    プレゼンテーションにカスタムUIを 好きな場所に追加できるようになりました さらに追加してみます

    ポップオーバーメニューを追加して 舞台装飾を変更します これで ロボット君を劇場から 南国の島に移動できます 『Tempest』にぴったりです

    このセットは多くの可能性を秘めています しかし 何かアレンジを加えたいところです 滝はどうでしょうか 雷雲もいいかもしれません

    それでも これらのものが アクションの核心を妨げないように 注意します これには 新しいクリッピングマージンを 使用します

    ボリュームを使うと新しいpreferred WindowClippingMargins APIで シーンの境界外にコンテンツを レンダリングできます

    このコンテンツは インタラクティブではありません したがって 視覚的な華やかさの ためだけに使用してください

    このような境界は システムによって 許可されない可能性があります これに対応するには windowClippingMargins環境変数で windowClippingMargins環境変数を 使用します

    実際に見てみましょう

    preferredWindowClippingMargins APIで 希望するクリッピングマージンを指定できます ここでは 下部にマージンを設定したいです

    maxWaterfallHeightを 1メートル単位で ポイントに変換するために PhysicalMetricから得た pointsPerMeter係数を掛けています

    次にwindowClippingMargins 環境変数で 許可されたマージンを読み取ります

    これにより 滝を拡大縮小して マージン内でレンダリングできます

    許可されたものに関係なく 滝のモデル全体が常にレンダリング されるように マージンと 滝の高さの最小値を取ります

    すると こうなります とても良くなりました 雲が良い嵐の雰囲気を加え 滝はベースプレートの下に レンダリングされます コンテンツを上にずらさずに 島と そこにいるロボットに 焦点を当て続けます

    BOTanistが注油直後だといいですね

    これで 私たちの最新の演劇作品は これまで以上にリアルに感じらます 平面へのスナップと クリッピングマージンにより コンテンツは 私たちの物理的な 空間に適応します プレゼンテーションを使って 完璧なシーンを作り上げるための 強力なインターフェースを作成できます

    それでは アプリのイマーシブ体験を向上 させるために何ができるか見てみましょう

    イマーシブ空間は 空間的な体験を 周囲にもたらします visionOS 26は イマーシブ空間で さらに多くのことを行うための 素晴らしい新しい方法をもたらします

    ワールドリセンタリングイベントの イマーシブスタイルの新機能 macOS でのリモートイマーシブ空間 Metal によるレンダリングのための コンポジターベースのイマーシブ空間を紹介しましょう 自分の空間を移動するとき ユーザーはDigital Crownを長押して 周囲のアプリの体験を 再センタリングできます

    アプリがARKitデータを使用する場合 保存しておいた位置情報が 無効になることがあります

    新しいonWorldRecenterビュー 修飾子で ワールドリセンターリングイベントを聞く ことができ 通知を受けることができます

    これは新しい座標系に基づいて 位置を再計算し保存するのに 非常に役立ちます

    visionOS 26には イマーシブ空間に利用できる 様々な没入スタイルの 新しいカスタマイズも含まれています

    段階的なイマーシブスタイルは イマーシブ空間を部分的に提示しながら 現実世界にユーザーを留めておく 素晴らしい方法です

    イマーシブコンテンツは ポータル内に表示され Digital Crownを回すことで サイズを変更できます

    この没入範囲は 段階的な イマーシブスタイルでカスタマイズできます

    visionOS 26では このポータルの アスペクト比もカスタマイズできます 既存の横向きのアスペクト比 または新しい縦向きのアスペクト比を 使用できます

    iPhoneゲームをApple Vision Proで プレイする場合や 多くの動きが含まれる体験には 縦向きのアスペクト比を検討してください 周囲が安定していることで ユーザーはより快適に感じることができます

    このアスペクト比は 没入範囲と同様に段階的なスタイルの パラメータで指定できます

    段階的なスタイルに加えて イマーシブ空間の 混合イマーシブスタイルにも 新しいカスタマイズがあります

    イマーシブスタイルを mixedに設定すると イマーシブ空間のコンテンツは 周囲に溶け込みます

    これはこのアプリのデフォルトスタイルです

    visionOS 26ではイマーシブ空間の コンテンツがシステム環境とも融合できます つまり 月にいながらロボットの最新作を 観ることができます

    これを可能にするために 共存動作を持つ immersiveEnvironmentBehavior シーン修飾子を使用してください

    混合イマーシブ空間で ユーザーが現実世界の周囲を認識する 必要がない場合にこれを行ってください

    アプリに追加した小道具を 気に入っていますが 新しいシーンを作成する際は 自分のモデルを持ち込みたいと 思っていることもわかっています これらのモデルはお気に入りの macOSアプリで作成されるかもしれません

    これらのモデルをMacから 直接使用できるようにするために 同じステージ作成機能を備えたアプリを macOSに導入しました

    より迅速な反復のために macOSからvisionOSにステージを 移行せずに 直接イマーシブ空間として シーンを プレビューできたらすごいですよね

    visionOS 26とmacOS Tahoeは それを可能にする RemoteImmersiveSpacesを 追加します リモートイマーシブ空間を使用すると CompositorLayerでMetalを使って Macのアプリコードや リソースからコンテンツをレンダリングし

    Vision Proでイマーシブ体験として 表示できます

    アプリでこの機能を実際に見てみましょう

    Macアプリで Metalを使用して 新しいイマーシブ空間を構築し ボタンを 追加しました

    これをクリックすると ターゲットの Vision Proデバイスの選択を求められます

    Vision Proで接続リクエストを 承認します

    するとすぐに ImmersiSpaceが開き ロボットの最新ショーに追加した 新しい小道具を見ることができます

    これを実現するために CompositorLayerを含む CompositorLayerが含まれています

    これがvisionOSで表示され メインステージのような他のシーンは 引き続きMacで直接表示されます

    CompositorLayerとARKitSessionを リモートVision Proデバイスに適応させる 方法について詳しくは 「What’s new in Metal rendering for immersive apps」をご覧ください

    リモートイマーシブ空間で CompositorLayerを使用すると Metalを使ったイマーシブ体験を 作成するための多くの可能性が得られます

    ただし CompositorLayerは ビューではないため ImmersiveContentなど ビューを 必要とするコンテキストでは使用できません

    これまで 環境変数やView修飾子が CompositorLayerには 利用できないことを意味していました

    visionOS 26では 新しいCompositor Contentビルダータイプが追加され CompositorLayerでSwiftUIの 全機能を使用できるようになりました

    これにより 環境変数にアクセスしたり 修飾子を追加したり SwiftUIビューと同じように 状態変数を使用することもできます

    CompositorContentは scenePhaseやopenWindowなど 多くの便利な環境変数と onImmersionChangeやonWorld Recenterなどの修飾子を提供します

    これらにより CompositorLayerは リモートイマーシブ空間でも visionOSで直接動作する 通常の空間でも 強力に使用できるようになります

    アプリのアップグレードにより CompositorContentを使用することは 使用可能なイマーシブ空間修飾子の 一部を見直し アプリにどのように適用できるかを見直す 素晴らしい方法となりました

    以上がイマーシブ空間の新機能です 環境再センタリングイベント 新しいイマーシブスタイルのカスタマイズ RemoteImmersiveSpaceによる Macからのイマーシブ空間の創出 そしてCompositorContentについて 説明しました

    これらの機能により アプリの見た目は 素晴らしいものになりました 実際 これらの素晴らしい ボリュメトリック体験を 他のアプリにも追加したいと思っています

    ただし 一部のアプリはUIKitで 構築されており UIKitはボリュームや イマーシブ空間をサポートしていません しかし 今はシーンブリッジングによって それが可能になります

    シーンブリッジングを使用すると 既存のUIKitアプリと 既存のUIKitアプリとイマーシブ空間を 統合できます

    例えば Safariは SwiftUIビューを使用していますが UIKitライフサイクルで構築されています

    Safariは新しい空間ブラウジング機能に シーンブリッジングをうまく活用しています

    その方法を見てみましょう

    SwiftUIのシーンをUIKitアプリに ブリッジするには まず UIHostingSceneDelegateを継承する クラスタイプを作成します

    このタイプを使用して 使い慣れたのシーンボディ構文で rootSceneプロパティに SwiftUIシーンを宣言できます

    これで 他のUIKitシーンと同様に UISceneSessionActivationRequestを 作成して このシーンをリクエストできます

    この場合 シーンを宣言する ホスティングデリゲートクラスと 開きたいシーンのIDを渡します

    あとは activateSceneSessionを使用して このリクエストを送信するだけです

    configurationForConnectingで ホスティングデリゲートクラスを設定すると 外部イベントに対応することもできます

    このAPIには 既存のmacOS AppKitアプリに SwiftUIシーンをブリッジするための 対応するAppKit APIも含まれています

    このアプリは現在 visionOS 26の 新機能を最大限に活用しており 位置の固定 表面へのスナップ Macからのリモートオープンなどが 可能です 友達に見せるのが楽しみです

    ご自身のアプリを見直して シーンを見直して 位置の固定と復元機能を 最大限に活用しているか確認してください

    スナップやクリッピングマージンを使用して シーンを周囲に適応させることができます

    そしてリモートイマーシブ空間を使って macOSアプリのコンテンツを Vision Proで没入させてください

    幕は降りますが アプリでは1シーンずつ ショーが続きます ご視聴ありがとうございました

    • 4:10 - Disabling restoration

      // Disabling restoration
      
      WindowGroup("Tools", id: "tools") {
          ToolsView()
      }
      .restorationBehavior(.disabled)
    • 4:36 - Disabling restoration in UIKit

      // Disabling restoration
      
      windowScene.destructionConditions = [
          .systemDisconnection
      ]
    • 5:02 - Specifying launch window

      // Specifying launch window
      
      @AppStorage("isFirstLaunch") private var isFirstLaunch = true
      
      var body: some Scene {
          WindowGroup("Stage Selection", id: "selection") {
              SelectionView()
          }
      
          WindowGroup("Welcome", id: "welcome") {
              WelcomeView()
                  .onAppear {
                      isFirstLaunch = false
                  }
          }
          .defaultLaunchBehavior(isFirstLaunch ? .presented : .automatic)
      
          // ...
      }
    • 6:39 - "suppressed" behavior

      // "suppressed" behavior
      
      WindowGroup("Tools", id: "tools") {
          ToolsView()
      }
      .restorationBehavior(.disabled)
      .defaultLaunchBehavior(.suppressed)
    • 7:44 - Unique window

      // Unique window
      
      @AppStorage("isFirstLaunch") private var isFirstLaunch = true
      
      var body: some Scene {
          // ...
      
          Window("Welcome", id: "welcome") {
              WelcomeView()
                  .onAppear {
                      isFirstLaunch = false
                  }
          }
          .defaultLaunchBehavior(isFirstLaunch ? .presented : .automatic)
      
          WindowGroup("Main Stage", id: "main") {
              StageView()
          }
      
          // ...
      }
    • 10:24 - Surface snapping

      // Surface snapping
      
      @Environment(\.surfaceSnappingInfo) private var snappingInfo
      @State private var hidePlatform = false
      
      var body: some View { 
          RealityView { /* ... */ }
          .onChange(of: snappingInfo) {
              if snappingInfo.isSnapped &&
                  SurfaceSnappingInfo.authorizationStatus == .authorized
              {
                  switch snappingInfo.classification {
                      case .table:
                          hidePlatform = true
                      default:
                          hidePlatform = false
                  }
              }
          }
      }
    • 14:41 - Clipping margins

      // Clipping margins
      
      @Environment(\.windowClippingMargins) private var windowMargins
      @PhysicalMetric(from: .meters) private var pointsPerMeter = 1
      
      var body: some View {
          RealityView { content in
              // ...
              waterfall = createWaterfallEntity()
              content.add(waterfall)
          } update: { content in
              waterfall.scale.y = Float(min(
                  windowMargins.bottom / pointsPerMeter,
                  maxWaterfallHeight))
              // ...
          }
          .preferredWindowClippingMargins(.bottom, maxWaterfallHeight * pointsPerMeter)
      }
    • 16:44 - World recenter

      // World recenter
      
      var body: some View {
          RealityView { content in
              // ...
          }
          .onWorldRecenter {
              recomputePositions()
          }
      }
    • 17:58 - Progressive immersion style

      // Progressive immersion style
      
      @State private var selectedStyle: ImmersionStyle = .progressive
      
      var body: some Scene {
          ImmersiveSpace(id: "space") {
              ImmersiveView()
          }
          .immersionStyle(
              selection: $selectedStyle,
              in: .progressive(aspectRatio: .portrait))
      }
    • 18:37 - Mixed immersion style

      // Mixed immersion style
      
      @State private var selectedStyle: ImmersionStyle = .progressive
      
      var body: some Scene {
          ImmersiveSpace(id: "space") {
              ImmersiveView()
          }
          .immersionStyle(selection: $selectedStyle, in: .mixed)
          .immersiveEnvironmentBehavior(.coexist)
      }
    • 20:14 - Remote immersive space

      // Remote immersive space
      
      // Presented on visionOS
      RemoteImmersiveSpace(id: "preview-space") {
          CompositorLayer(configuration: config) { /* ... */ }
      }
      
      // Presented on macOS
      WindowGroup("Main Stage", id: "main") {
          StageView()
      }
    • 20:48 - 'CompositorLayer' is a 'CompositorContent'

      // 'CompositorLayer' is a 'CompositorContent'
      
      struct ImmersiveContent: CompositorContent {
          @Environment(\.scenePhase) private var scenePhase
      
          var body: some CompositorContent {
              CompositorLayer { renderer in
                  // ...
              }
              .onImmersionChange { oldImmersion, newImmersion in
                  // ...
              }
          }
      }
    • 23:00 - Scene bridging

      // Scene bridging
      
      import UIKit
      import SwiftUI
      
      // Declare the scenes
      class MyHostingSceneDelegate: NSObject, UIHostingSceneDelegate {
          static var rootScene: some Scene {
              WindowGroup(id: "my-volume") {
                  ContentView()
              }
              .windowStyle(.volumetric)
          }
      }
      
      // Create a request for the scene
      let requestWithId = UISceneSessionActivationRequest(
          hostingDelegateClass: MyHostingSceneDelegate.self, id: "my-volume")!
      
      // Send a request
      UIApplication.shared.activateSceneSession(for: requestWithId)

Developer Footer

  • ビデオ
  • WWDC25
  • SwiftUIによるvisionOSのシーンの設定
  • メニューを開く メニューを閉じる
    • 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.
    利用規約 プライバシーポリシー 契約とガイドライン