WWDC26の Session 278 は、可変サイズのウインドウと、UIScreen.main や画面全体のboundsに依存しない実装を扱っています。ここからの最短解は明確です。
症状: UIScreen.main、screen bounds、画面方向でレイアウトや描画条件を決めている。
最短解: 表示機器の属性は現在のUIWindowScene、レイアウトはview.bounds、倍率とサイズ特性は現在のtrait環境、シーン単位の管理だけeffectiveGeometryへ分けます。
この判断が必要な人
対象は、UIScreen.mainを大量に使うUIKitや混合アーキテクチャの保守担当者です。APIの置換規則をチームで統一したいアーキテクト、Xcode 27、iPhone Mirroring、iPadの可変ウインドウを回帰確認するQA・CI担当者にも関係します。
折りたたみ式iPhoneの名称、寸法、価格、最終的なウインドウ形状は、現時点ではAppleの確定情報ではありません。したがって、伝聞の端末サイズを基準に実装するのではなく、すでに確認できる可変ウインドウの文脈へ先に移行します。
注意:
UIScreen.mainをUIWindowScene.screenへ機械的に置き換えるだけでは不十分です。前者で取得していた値が「物理ディスプレイの属性」なのか、「その画面で使えるレイアウト領域」なのかを、呼び出し単位で確認してください。
まずデータの意味で代替案を絞る
同じUIScreen.main.boundsでも、実際の目的は異なります。広告表示の密度、ウインドウ内のカード配置、自作キャンバスの倍率、横向き時の分岐を、同じ画面オブジェクトで処理していることが移行を難しくします。
| 実際に必要なデータ | 第一候補 | 適用する層 | 避ける判断 |
|---|---|---|---|
| 表示機器の画面属性 | 現在のUIWindowScene.screen |
scene・window | グローバルな画面参照 |
| ビューが使える領域 | view.bounds |
view・view controller | screen boundsからの推定 |
| 親コンテナ内の配置領域 | 親ビューのbounds、またはレイアウトガイド | container | 端末の物理寸法 |
| scene全体の幾何情報 | UIWindowScene.effectiveGeometry |
scene管理 | 子ビューのレイアウトへの直接流用 |
| 倍率・サイズ特性 | 現在のtraitCollection |
view・controller | 端末名や方向からの推測 |
AppleはUIScreen.mainを、現在の実行文脈を表す安全な入口として扱わない方向を示しています。公式の UIScreen.mainのAPI説明 でも、非推奨状態と、より適切なコンテキストから画面を取得する考え方を確認できます。
この表の使い方は単純です。コードが「どのディスプレイか」を知りたいならscene側へ上げます。「この部品を何ポイントで置くか」を知りたいならview側へ下ろします。
screenを使う場合と、使わない場合を分ける
表示機器の属性が必要なケースでは、ビューからwindow、windowSceneへたどります。
guard let screen = view.window?.windowScene?.screen else {
return
}
let scale = screen.scale
このscreenは、対象ビューが現在所属しているsceneの画面です。複数sceneや外部ディスプレイを扱う場合、グローバルなUIScreen.mainよりもデータの所属先を説明しやすくなります。Appleの UIWindowSceneドキュメント も、ウインドウをsceneの文脈で扱う設計を前提にしています。
ただし、view.windowがまだnilの段階で画面を強制取得してはいけません。initや、windowへ組み込まれる前の早すぎるライフサイクルでこの値を必要とするなら、処理を遅らせるか、必要なコンテキストを依存性として渡します。
一方、レイアウトのためにscreenを読むコードは、ほとんどの場合、対象ビューのサイズへ変更します。
let availableSize = view.bounds.size
UIView.boundsは、そのビューのローカル座標系における領域です。詳しい意味は AppleのUIView.boundsリファレンス で確認できます。親の制約で横幅が縮んでいる子ビューに対し、物理画面の幅を渡しても、実際の配置可能領域にはなりません。
可変ウインドウでは「画面」より「利用可能領域」を測る
iPadの可調整ウインドウやiPhone Mirroringでは、物理端末の画面寸法とアプリが現在取得している領域が一致するとは限りません。ミラーリングの利用条件自体も端末、Mac、アカウントなどの組み合わせに依存するため、AppleサポートのiPhone Mirroring条件 を確認したうえで検証環境を作る必要があります。
シーン全体のウインドウ配置を管理するコードだけは、effectiveGeometryの候補になります。たとえば、sceneのサイズ変更に応じてウインドウ管理状態を更新する処理です。ただし、それを個々のビューのカード幅やテキスト折り返しの計算へ直接渡すのは避けます。
| 判定対象 | 読む場所 | 実装上の意味 | よくある誤り |
|---|---|---|---|
| 子ビュー内のボタン配置 | 子ビューのbounds |
その部品が使えるローカル領域 | UIScreen.main.boundsを代入 |
| コンテナ内の一覧列数 | コンテナの利用可能サイズ | 親の制約を反映した幅 | 端末の縦横だけで分岐 |
| sceneのウインドウ管理 | effectiveGeometry |
scene全体の幾何情報 | ビュー階層へ無条件に伝播 |
| 描画画像の倍率 | 現在のtrait環境 | 対象表示文脈に合わせた描画 | 固定倍率でキャッシュ |
| 表示機器の属性確認 | 現在のsceneのscreen | 実際の所属ディスプレイ | mainを常に正解とみなす |
effectiveGeometryを使う場合は、AppleのUIWindowScene.effectiveGeometryの説明 と照合してください。プロパティ名が似ているからという理由で、viewのboundsの代用品にしてはいけません。
倍率、trait、方向は同じ問題として扱わない
旧コードでは、画面のscale、size class、方向を一つの条件式にまとめがちです。しかし、これらは別の指標です。
- 自作描画のピクセル密度を決めるなら、描画対象ビューのtrait環境を確認します。
- レイアウトの広さを決めるなら、viewやコンテナの実サイズを使います。
- 機器の属性が必要なら、所属する
UIWindowSceneのscreenを使います。 - 横幅の分岐に画面方向を使うのは避けます。縦向きでも広いウインドウ、横向きでも狭いウインドウが成立するためです。
traitの変化に応答する設計は、Appleのtrait変更対応ガイド に沿って、現在のビューまたはコントローラーの環境で更新します。方向値を「狭い」「広い」の代理にすると、ウインドウのリサイズ時に条件が更新されない可能性があります。
誤った前提と、正しいコンテキスト
// 誤り:物理画面の幅をレイアウト分岐に使用
let width = UIScreen.main.bounds.width
if width < 600 {
showCompactLayout()
}
// 修正:対象コンテナが現在使える幅で判断
let width = containerView.bounds.width
if width < compactThreshold {
showCompactLayout()
}
ここで重要なのは、UIScreen.mainを短いコードへ変えることではありません。compactThreshold自体を端末の噂寸法から作らず、アプリのレイアウト要件として定義することです。
移行コストは呼び出しの意味で見積もる
コードレビューでは、次の四つに分類すると判断がぶれません。
| 分類 | 典型的な旧処理 | 移行先 | リスク |
|---|---|---|---|
| 直接置換に近い | sceneの画面属性を読む処理 | 現在のsceneからscreen | window未接続時のnil |
| scene層へ移す | ウインドウ配置やscene管理 | UIWindowScene |
呼び出し元の設計変更 |
| view層へ下ろす | 部品幅、余白、折り返し | view.boundsや制約 |
座標系の見直し |
| 再設計が必要 | 方向や端末幅で業務判断 | 実サイズ・trait・状態へ分割 | 暗黙の仕様が隠れている |
旧OSとの互換性が必要でも、新しいグローバルシングルトンを作るのは避けます。ScreenContextProvidingのような薄いラッパーを設け、scene、window、view、traitのどれを渡したかを明示すると、段階移行の範囲を制御できます。
監査の合格条件は、「置換後の値がどのscene、window、view、trait環境に属するかを説明できること」です。説明できない値は、型がコンパイルできても、可変ウインドウ対応としては未完了です。
FAQ:移行時に判断が割れやすい箇所
上の選択表をコード監査へ適用すると、長尾の疑問にも同じ基準で答えられます。特にXcode 27では、固定端末で表示できたかだけで合格にしないことが重要です。
回帰確認で外せない観点
- [ ]
UIScreen.mainの各呼び出しを、機器属性、scene幾何、view領域、trait環境のいずれかに分類しました。 - [ ]
view.windowが未接続のライフサイクルで、screenを強制取得していません。 - [ ] レイアウトの幅、高さ、列数、折り返しをscreen boundsから計算していません。
- [ ] Xcode 27でウインドウを手動変更し、境界付近のレイアウトを確認しました。
- [ ] iPhone Mirroringで倍率、自作描画キャッシュ、タップ座標を個別に確認しました。
- [ ] iPadの可変ウインドウと複数sceneで、同じ値をグローバルに共有していません。
- [ ] 実機の主要経路でも、起動直後、scene接続後、サイズ変更後を確認しました。
- [ ] CIではテスト対象のXcode、OS、ウインドウ条件を記録し、再現時に同じ条件を再利用できます。
単一の開発用Macで順番に確認する方法は、環境構築が簡単な反面、Xcode 27、iPhone Mirroring、iPad経路を切り替えるたびに状態が変わります。複数のMacを並行利用する方法は管理対象が増えますが、同じ変更を異なるウインドウ条件へ同時に流せます。
MacHTMLの 開発環境とコンソールの案内 を使う場合も、先に必要なXcode、シミュレーターまたは実機経路、検証するscene条件を整理してください。利用前後の手順や接続条件は MacHTMLのヘルプ で確認できます。特定の構成や性能を、ここで未確認のまま前提にしてはいけません。
最後に、現在のMac環境とレンタル環境を比べる
手元のMacだけで進める方法は、長期的に同じ構成を使える点が強みです。ただし、Xcode 27の可変ウインドウ、iPhone Mirroring、iPad回帰を同じ期間に確保しようとすると、作業中の端末を占有します。OSやシミュレーター状態の差が残り、失敗した条件を別の担当者が再現しにくい点も負担です。
MacHTMLのレンタル環境なら、手元のMacを開発へ戻しながら、必要な期間だけ追加の検証環境を確保する判断ができます。長期の安定した高負荷処理や物理ポート依存の検証には自所有機が向きますが、リリース前の一時的な並行回帰や、Xcode 27のウインドウ条件を増やしたい場面では、レンタルのほうが運用上の無駄を抑えやすいです。
まずはデータ意味の選択表でコードを分類し、現在のMacで不足する検証条件だけを切り出してください。そのうえで、必要な期間と接続手順を確認し、MacHTMLの環境を追加するか、自前の構成で継続するかを決めるのが安全です。
関連記事: iOS 27デベロッパベータの導入手順と安全な検証方法 iOS 27の実機・シミュレーターでAPIを検証する環境づくり Macクラウドノードを活用したiOS開発環境の整え方
新しい画面仕様の検証をMacHTMLで始めませんか
ブラウザから利用できるリモートMacで、実機に近い環境で表示やレイアウトを確認できます。 画面サイズやウインドウ、特性環境ごとの挙動を分けて検証し、移行時の不具合を効率よく見つけられます。 必要な期間だけMacの開発環境を利用できるため、アップデート前後の比較検証にも適しています。 チームで検証環境を共有しながら、画面に関する問題の再現と切り分けを進められます。