Skip to content
すべての記事

iPhone Duo のサイズクラス:閉じた・半開き・開いた状態を解説

iPhone Duo が閉じた・半開き・開いた状態で返すサイズクラス、向きではなくサイズクラスで対応すべき理由、SwiftUI と UIKit での実装コードを解説します。

AppleDuo 編集部公開 12分で読めます

ほかの言語:EnglishDeutschEspañolFrançaisTürkçe

このページの内容
  1. iPhone Duo は各姿勢でどのサイズクラスを返す?
  2. iPhone Duo で向きではなくサイズクラスを使うべき理由は?
  3. SwiftUI でサイズクラスを読み取るには?
  4. UIKit で traitCollection からサイズクラスを読み取るには?
  5. ArrangementView のペイン内でサイズクラスはどう機能する?
  6. Xcode の Device Hub で iPhone Duo の姿勢をテストするには?
  7. まとめ

アプリを iPhone Duo に対応させる前に 1 つしか変更する時間がないなら、サイズクラスに取り組んでください。このデバイスには 2 つのディスプレイと複数の姿勢があり、姿勢ごとにアプリが使えるスペースが異なります。iPhone Duo のサイズクラスを正しく扱えば、デバイスモデルを一度も判定することなく、1 つのレイアウトですべての姿勢に対応できます。

要点は iOS デベロッパ @sarunw の言葉に集約されます。閉じれば iPhone Duo は iPhone、開けば iPad です。この記事では、それが各姿勢で何を意味するのか、なぜ向きは判断材料として不適切なのか、そして SwiftUI と UIKit でサイズクラスを読み取る方法を説明します。ここでの内容はすべて、Apple の Tech Talk、Apple のデベロッパフォーラム、出典を示したデベロッパの報告に基づいています。これらの API は iOS 27.1 と Xcode 27.1 で提供され、リリース間で詳細が変わる可能性があります。

iPhone Duo は各姿勢でどのサイズクラスを返す?

サイズクラスは、アプリが使えるスペースを水平・垂直それぞれ compact または regular で大まかに表したものです。iPhone Duo では、どの組み合わせになるかはアクティブなディスプレイによって決まり、それはデバイスをどこまで開いているかによって決まります。

Apple の Tech Talk「Prepare your app for iPhone Duo」によると、外側ディスプレイは「ほかの iPhone モデルと同じように動作」し、内側ディスプレイは両方向とも regular を返すため、サイドバーのようなコンテンツを置く余裕があります。@sarunw の整理では、半開きの姿勢と両方の向きも加わっています。

姿勢ディスプレイ水平垂直相当するもの
閉じた状態、縦向き外側CompactRegular縦向きの iPhone
閉じた状態、横向き外側CompactCompact横向きの iPhone
半開き(本のような状態)内側RegularRegulariPad
開いた状態、縦向き内側RegularRegulariPad
開いた状態、横向き内側RegularRegulariPad

用語について補足します。@sarunw は「folded」を閉じた状態の意味で使っています。Apple の Tech Talk では、半開きの姿勢を「本のように部分的に折り曲げた状態」と表現しています。この記事では、「閉じた状態」は外側ディスプレイを使用中であること、「半開き」は内側ディスプレイがヒンジで曲がっていることを指します。

規模の目安として、Pasquale Pillitteri は縦向きで外側ディスプレイを 466 × 678 ポイント、内側ディスプレイを 626 × 890 ポイントと報告しています。これらの数値に依存したコードを書くべきではありませんが、内側ディスプレイが regular の幅になる理由はわかります。縦向きのどの iPhone よりも幅が広いのです。

iPhone Duo で向きではなくサイズクラスを使うべき理由は?

かつては、向きが「2 列目を置く余裕があるか」を判断する手軽な目安でした。iPhone Duo ではそうはいきません。Apple のガイダンスは明確で、レイアウトのために向きを判定するのは避け、代わりにサイズクラスを使うよう求めています。ここで向きが信頼できない理由は 2 つあります。

  • 内側ディスプレイはサポートする向きを無視する。 Apple によると、内側ディスプレイはアプリがサポートするインターフェイスの向きに従いません。アプリを縦向きに固定して向きで分岐していると、想定していなかったレイアウトになります。
  • 内側ディスプレイではどちらの向きも regular。 内側ディスプレイの縦向きと横向きは同じサイズクラスを返すため、向きを判定しても使える幅については何もわかりません。

Apple はフォーラムの回答で、デバイスの判定についても同じことを述べています。あるスレッドでは DTS エンジニアが「特定の画面という観点で考えず、レイアウトに使える利用可能なスペースだけを考えてください」と助言しています。別のスレッドでは Apple のエバンジェリストが、デバイス固有のロジックを避け、サイズクラスを活用し、すべての向きをサポートするよう勧めています。これは、iOS 27 で iPad 上や Mac の iPhone ミラーリングでサイズ変更できるようになった iPhone アプリにも当てはまります。

姿勢を表す専用のトレイトもありません。UITraitCollection が折り目を公開しているかという質問に、Apple のエンジニアはスレッド 848007 で「ご質問のような種類の UITraitCollection トレイトはありません」と回答しています。レイアウトはサイズクラスで決めます。折り目そのものは予約領域とヒンジ API で扱います。

SwiftUI でサイズクラスを読み取るには?

SwiftUI では、両方のサイズクラスが環境に入っています。レイアウトを決めるビューで読み取れば、デバイスを開く、閉じる、回転させるたびに SwiftUI がそのビューを再描画します。環境キーは Apple が Tech Talk で示しているものです。

struct LibraryView: View {
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @Environment(\.verticalSizeClass) private var verticalSizeClass

    var body: some View {
        if horizontalSizeClass == .regular {
            // 内側ディスプレイ:リストと詳細を横に並べる余裕がある。
            HStack(spacing: 0) {
                AlbumList()
                AlbumDetail()
            }
        } else {
            // 外側ディスプレイ:通常の iPhone と同じく 1 列。
            AlbumList()
        }
    }
}

このサンプルは、幅だけを基準に 1 列と 2 列のレイアウトを切り替えます。高さに関する判断には垂直のサイズクラスを使います。たとえば、外側ディスプレイが横向きで両方の値が compact のときに大きなヘッダを隠す、といった場合です。

自分で実装する前に、システムのコンテナがすでに対応していないか確認しましょう。Apple によると、NavigationSplitView はデバイスを閉じると 1 つのスタックに折りたたまれ、開くと列を並べるか重ねて表示します。また TabView はすべての姿勢に適応します。アプリでこれらのコンテナを使っていれば、サイズクラスへの対応の多くはすでに済んでいます。

UIKit で traitCollection からサイズクラスを読み取るには?

UIKit では、サイズクラスはすべてのビューとビューコントローラのトレイトコレクションにあります。traitCollection.horizontalSizeClass と traitCollection.verticalSizeClass です。iOS 17 以降は、非推奨の traitCollectionDidChange(_:) をオーバーライドする代わりに、トレイトの変更を登録できます。

final class LibraryViewController: UIViewController {
    private let detailContainer = UIView()
    private var listWidthConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        registerForTraitChanges(
            [UITraitHorizontalSizeClass.self, UITraitVerticalSizeClass.self]
        ) { (self: Self, _: UITraitCollection) in
            self.updateLayout()
        }
        updateLayout()
    }

    private func updateLayout() {
        let isWide = traitCollection.horizontalSizeClass == .regular
        detailContainer.isHidden = !isWide
        listWidthConstraint.isActive = isWide
    }
}

このコントローラは、幅が regular のときだけ詳細コンテナを表示し、デバイスを開いたときなど、いずれかのサイズクラスが変わるたびに更新します。SwiftUI と同様に、適する場面では UISplitViewController や UITabBarController を優先しましょう。Apple によると、これらは折り目に自動で適応します。

同じ Tech Talk で紹介されている関連する 2 つの習慣も、サイズクラスに基づくレイアウトを正しく動作させるのに役立ちます。UIScreen.main.scale を traitCollection.displayScale に置き換えてください。2 つのディスプレイを持つデバイスでは「メインスクリーン」が曖昧だからです。また、セーフエリアのインセットは辺ごとに個別に扱ってください。iPhone Duo ではインセットが不均一なことが多いためです。

ArrangementView のペイン内でサイズクラスはどう機能する?

iOS 27.1 の新機能である ArrangementView は、スペースと姿勢に応じて、プライマリとセカンダリのビューを横に並べる、縦に積む、または重ねて配置します。Apple の Tech Talk「Strike a pose with adaptive layouts on iPhone Duo」では、レイアウトを決める際に考慮する入力として、「ビューの水平・垂直のサイズクラス」、ビューのアスペクト比、そして折り目などの division 領域がアクティブかどうかが挙げられています。

実践的なポイントは、ペインがウィンドウの値を引き継ぐと決めつけず、各ペインの中でサイズクラスを読み取ることです。内側ディスプレイの半分を割り当てられたペインは、ディスプレイ全体よりはるかに幅が狭くなります。@sarunw は iPhone Duo で各ビューが受け取るサイズクラスの図を公開しています。画像なので、ここでの要約に頼らず、ペインごとの値は元の投稿で確認してください。

折りたたみも重要です。Apple の DTS エンジニアはスレッド 847800 で、現在のアスペクト比、姿勢、または compact のサイズクラスで分割を満たせない場合、ArrangementView は「1 つのビューだけを表示するよう折りたたまれる」と説明しています。残るのは .layoutPriority が高いほうのビュー、またはデフォルトではプライマリビューです。セカンダリペインに必須のコントロールがある場合は、幅が compact のときにもユーザーがそれにアクセスできる別の手段を用意してください。

struct EditorView: View {
    var body: some View {
        ArrangementView {
            VideoPreview()
        } secondary: {
            EditingControls()
        }
        .arrangementViewStyle(.split)
    }
}

struct VideoPreview: View {
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    var body: some View {
        PreviewCanvas()
            .toolbar {
                if horizontalSizeClass == .compact {
                    // コントロールのペインが隠れている可能性があるので、ツールバーから提供する。
                    ToolbarItem { EditingControlsButton() }
                }
            }
    }
}

ArrangementView と .arrangementViewStyle(.split) の呼び出しは、Apple が Tech Talk で示しているとおりです。幅が compact のときのフォールバックは、同じフォーラムスレッドで提案されているアプローチに従っています。

Xcode の Device Hub で iPhone Duo の姿勢をテストするには?

サイズクラスを確認するのに実機は必要ありません。Apple の Tech Talk に手順が示されています。Xcode 27.1 で iPhone Duo シミュレータを選び、Device Hub でアプリを実行し、下部のコントロールボタンでデバイスを開く、閉じる、回転させる、折り曲げることができます。Device Hub とフルスクリーン表示のどちらにも Xcode 27.1 が必要です。

上の表のすべての行を順に確認してください。各姿勢で次の点を確かめます。

  1. レイアウトが向きではなくサイズクラスに合っていること。
  2. テキストとコントロールが、上下だけでなくすべての辺でセーフエリア内に収まっていること。
  3. 半開きのときに、重要なものが折り目をまたいでいないこと。
  4. 遷移の前後で状態が保たれること:スクロール位置、テキスト入力、現在の選択。

次に、内側ディスプレイでより狭い幅をテストします。Apple は、ホームインジケータでアプリを画面の片側にドラッグして Split View のマルチタスクに入り、続いて反対側にもドラッグする方法を勧めています。フォーラムの DTS エンジニアは、アプリが regular の幅全体より狭いスペースしか得られない構成として、内側ディスプレイで 2 つのアプリを開いた状態を確認すべきだと特に指摘しています。@sarunw によると、Xcode 27.2 の Device Hub ではメモリ不足、スローモーションのアニメーション、シェイク、落下を擬似的に発生させることもでき、遷移の途中で起きるバグを追うときに役立ちます。

ゲームでは半開きの状態に特に注意が必要です。regular の幅を返す姿勢でも、物理的には 2 つに分かれていることがあります。Greens Mini Golf のようなゲームはこれを活用しており、下半分にパッティンググリーン、立てた上半分にキャディカメラを表示します。サイズクラスでは折り目の位置はわかりません。それは予約領域とヒンジ API の役割です。

まとめ

  • 閉じた状態の iPhone Duo は iPhone のサイズクラスを返します。縦向きでは幅が compact・高さが regular、横向きでは両方向とも compact です。
  • 半開きまたは開いた状態では、内側ディスプレイはどちらの向きでも幅・高さともに regular を返し、iPad と同じになります。
  • 向きやデバイスモデルで分岐しないでください。内側ディスプレイはサポートする向きを無視し、Apple は利用可能なスペースに合わせて対応するよう推奨しています。
  • SwiftUI では環境から、UIKit では traitCollection から horizontalSizeClass と verticalSizeClass を読み取り、すでに適応するシステムのコンテナを優先しましょう。
  • ArrangementView の中ではペインごとにサイズクラスを読み取り、分割が 1 つのビューに折りたたまれる場合に備えましょう。
  • Xcode 27.1 の Device Hub で、すべての姿勢と Split View をテストしましょう。

サイズクラスは最初の一歩です。次は、iPhone Duo の縦向きツールバーのガイドでバーが画面の横に移動する仕組みを確認し、iPhone Duo 対応チェックリストをひととおり実施するか、Built for the fold でヒンジをすでに活用しているゲームをご覧ください。

よくある質問

iPhone Duo の内側ディスプレイのサイズクラスは?

内側ディスプレイは、半開きでも完全に開いた状態でも、縦向き・横向きのどちらでも水平・垂直ともに regular のサイズクラスを返します。これはフルスクリーンの iPad アプリと同じ組み合わせです。

iPhone Duo の外側ディスプレイのサイズクラスは?

外側ディスプレイはほかの iPhone モデルと同じように動作します。縦向きでは幅が compact・高さが regular、横向きでは幅・高さともに compact を返します。

iPhone Duo に対応するには、画面の向きやデバイスモデルを判定すべきですか?

いいえ。Apple はデバイス固有のロジックや向きの判定を避け、サイズクラスと利用可能なスペースに合わせて対応することを推奨しています。内側ディスプレイはアプリがサポートするインターフェイスの向きに従わないため、そこでは向きはレイアウトの判断材料として信頼できません。

iPhone Duo の折り目や姿勢を表す UITraitCollection のトレイトはありますか?

Apple のエンジニアはデベロッパフォーラムで、姿勢を表すトレイトコレクションのトレイトは存在しないと回答しています。レイアウトにはサイズクラス、折り目には予約領域を使い、折り曲げの状態そのものが必要ならヒンジ API を使います。

実機なしで iPhone Duo のサイズクラスをテストするには?

Device Hub の iPhone Duo シミュレータでアプリを実行します。Xcode 27.1 が必要です。コントロールでデバイスを開く、閉じる、回転させる、折り曲げることができ、内側ディスプレイでアプリを Split View にドラッグすれば、より狭い幅もテストできます。

出典

  1. Size classes on iPhone Duo: folded portrait, folded landscape, half-open and open · @sarunw on X
  2. Folded, iPhone Duo is an iPhone. Unfolded, it's an iPad. · @sarunw on X
  3. Start with size classes, layout margins and safe area insets · @sarunw on X
  4. Size classes of each view in ArrangementView on iPhone Duo · @sarunw on X
  5. Prepare your app for iPhone Duo · Apple Developer
  6. Strike a pose with adaptive layouts on iPhone Duo · Apple Developer
  7. Does the iPhone Duo inner display use a regular horizontal size class? · Apple Developer Forums
  8. Adapting an existing UIKit app for iPhone Duo at runtime · Apple Developer Forums
  9. Hinge articulation and UITraitCollection in custom view controllers · Apple Developer Forums
  10. How should ArrangementView behave across iPhone Duo display modes? · Apple Developer Forums
  11. iPhone Duo Apps, What Changes in Your Code and What to Do With Old Ones · Pasquale Pillitteri

折りたたみを、アプリの一部に。

AppleDuo は iPhone Duo を本当に活かしたアプリとゲームを紹介しています。App Store へのリンクを添えて送ってください。ほかの開発者の作品も見られます。

[email protected]