Size Class は、すべてのデバイスを各軸に沿って2つのカテゴリ(Compact(狭い/短い)とRegular(広い/長い))に分割する、iOSのアダプティブレイアウトメカニズムです。これらの値の組み合わせにより、iPhone、iPad、Mac Catalyst、CarPlayでのインターフェース表示が決まります。Apple Human Interface Guidelines、2024によると、Size Classを使用すると、Auto LayoutとUITraitCollectionを使用してすべてのデバイスで1つのstoryboardを構築できます。このシステムはiOS 8以降のすべてのiOSデバイスで動作します。
重要なポイント
Size Class は、iOS 8でAppleがアダプティブレイアウトを統一するために導入した、iOSの抽象的な画面分類です。特定のデバイスモデルを確認する代わりに、Size Classは水平と垂直の利用可能なスペースという2つの特性を定義します。各特性はCompact(限られたスペース)またはRegular(十分なスペース)の2つの値のいずれかを取ります。これらの値の組み合わせがトレイトコレクションを形成し、すべてのインターフェース要素に渡されます。
Size Class 以前は、開発者はiPhoneとiPadで個別のstoryboardを作成するか、コードでUI_USER_INTERFACE_IDIOM()チェックを使用していました。これにより、コードの重複、storyboardの肥大化、新しい画面サイズのサポートの困難さが生じていました。Size Classは普遍的なシステムを提供することでこの問題を解決しました。開発者は4つのCompact/Regularの組み合わせに対してインターフェースを設定し、iOSが自動的に適切なものを選択します。iPadでのSplit ViewとさまざまなiPhoneサイズの登場により、このシステムはアダプティブレイアウトに不可欠なものになりました。
Size Class は、現在の画面の幅と高さに基づいてiOSが計算し、方向とマルチタスクを考慮します。値は特定のピクセルに結びついていません — 論理的なカテゴリです。例えば、iPhone 16 Proをポートレートで使用する場合、水平はCompact、垂直はRegularです。同じiPhoneをランドスケープで使用する場合、両方の軸でCompactです。Split Viewでアプリが画面の1/3を占めるiPadは、水平がCompactになります(フルスクリーンモードではRegular)。システムは方向やSplit Viewの変更時に自動的にSize Classを更新します。
Size Class は、2つの軸に2つの値の4つの組み合わせを使用します。各組み合わせには、デバイスの種類と向きに応じた用途があります。これらの組み合わせを理解することは、iOS用のアダプティブインターフェースを設計する基礎です。このシステムは、iPhone、iPad、Mac Catalyst、CarPlayのすべての現在のAppleデバイスをカバーしています。Appleは、wAny hAny(ベースレイアウト)の組み合わせから設計を始め、特定の組み合わせに合わせて調整することを推奨しています。
wCompact hRegular — ポートレートのiPhone(一部のケースではPlus/Maxを除く)。wCompact hCompact — ランドスケープのiPhone SE/6/7/8。wRegular hRegular — 任意の方向のフルスクリーンiPad、ランドスケープのiPhone Plus/Max。wRegular hCompact — 狭いコンテンツのランドスケープiPad。各組み合わせは、どの制約と要素がアクティブかを決定します。開発者はInterface Builderで各組み合わせの外観を個別に設定できます。
Mac Catalyst では、Size Classは常にwRegular hRegular(フルサイズのインターフェース)です。つまり、iPadアプリのMacバージョンは最大のスペースを取得します。開発者はUIScreen.traitCollection.userInterfaceIdiomを使用して、MacとiPadを区別する追加チェックを行うことができます。MacでのSize Classは安定して動作しますが、CatalystアプリはSize Classを超えたマウスとキーボードの追加適応が必要になることがよくあります。
Size Class は、どのAuto Layout制約がアクティブか、どのインターフェース要素が表示されるか、サブビューがどのように配置されるかを決定します。開発者は異なるSize Classごとに異なる制約を設定でき、トレイトコレクションが変更されるとiOSが自動的に切り替えます。例えば、iPad(wRegular hRegular)では詳細付きテーブルがMaster-Detailで表示され、iPhone(wCompact hRegular)ではNavigation Stackで表示されます。これがSize Classを使用したアダプティブレイアウトの主なシナリオです。
Interface Builderでは、開発者はVary for TraitsボタンからSize Classの組み合わせを選択し、その組み合わせにのみ適用される制約を追加します。wAny hAnyに設定された制約は常に適用されます。特定の組み合わせに設定された制約は、Size Classが一致した場合にのみアクティブになります。組み合わせに特別な制約が設定されていない場合は、ベース制約が使用されます。Size Classが変更されると、iOSは制約セット間の遷移をアニメーション化します。
Interface BuilderのInstalledフラグ を使用すると、特定のSize Classの要素を非表示にできます。開発者は選択した組み合わせに対して要素をUninstalledとしてマークします。例えば、DetailsボタンはiPad(wRegular hRegular)でのみ表示され、iPhoneでは非表示になります。これはコードでisHiddenを管理するよりも簡単です。プログラムで非表示にするには、traitCollectionDidChangeをオーバーライドするか、willTransitionメソッドを使用して現在のSize Classを確認します。
Interface Builder は、Size Classを操作するためのビジュアルツールVary for Traitsを提供します。開発者は目的の組み合わせ(幅と高さ)を選択すると、Interface Builderがその組み合わせの画面プレビューを表示します。このモードで行われたすべての制約、サイズ、フォント、可視性の変更は、選択したSize Classにのみ適用されます。モードを終了すると設定が保存されます。このアプローチにより、異なるデバイス用の適応コードを書く必要がなくなります。
Interface BuilderでSize Classを設定 するには、開発者はstoryboardを開き、view controllerを選択して、下部パネルのVary for Traitsボタンをクリックします。次に、Width(Compact、Regular、Any)とHeight(Compact、Regular、Any)を選択します。インターフェースが選択した組み合わせの編集モードに切り替わります。すべての制約変更、要素の追加または削除は、この組み合わせにのみ適用されます。設定が完了したら、開発者はモードを終了します — 変更は特定のSize Classの組み合わせに保存されます。
AppleはwAny hAny(すべてのデバイスをカバーするベースの組み合わせ)のベースレイアウトから始めることを推奨しています。次に、問題のある組み合わせ(wCompact hRegular(ポートレートiPhone)とwRegular hRegular(iPad))のレイアウトを調整します。すべての組み合わせを設定する必要はなく、レイアウトが崩れるものだけを設定します。過剰な設定はメンテナンスを複雑にします。フォントサイズの正確な調整には、Size Classの代わりにDynamic Typeを使用します。フォントは画面サイズに自動的に適応します。
UITraitCollection は、現在のSize Classやその他の環境特性(フォースタッチ、ディスプレイスケール、ユーザーインターフェースイディオム)を含むiOSクラスです。各UIViewとUIViewControllerには、親から継承された独自のtraitCollectionがあります。開発者はtraitCollection.horizontalSizeClassとtraitCollection.verticalSizeClassを介してSize Classを取得し、これらはUIUserInterfaceSizeClass(.compact、.regular、.unspecified)を返します。Size Classの変更は、traitCollectionDidChangeをオーバーライドして追跡されます。
Size Classに合わせてUICollectionViewレイアウトを適応させる例を考えてみましょう。iPad(wRegular hRegular)では2列のUICollectionViewCompositionalLayoutを使用し、iPhone(wCompact hRegular)では1列を使用します。コードは水平Size Classをチェックし、適切なレイアウトを選択します。回転時やSplit Viewへの移行時に、iOSがtraitCollectionDidChangeを呼び出し、コントローラーがアニメーション付きでレイアウトを切り替えます。
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass == .Compact {
collectionView.collectionViewLayout = SingleColumnLayout()
} else {
collectionView.collectionViewLayout = DoubleColumnLayout()
}
}
traitCollectionDidChangeメソッド は、デバイスの回転、Split Viewへの出入り、外部ディスプレイの接続など、Size Classが変更されるたびに呼び出されます。このメソッドで、開発者はレイアウトを更新し、コレクションをリロードし、制約の優先順位を更新し、要素の可視性を変更します。Size Classが実際に変更されたかどうか(他の特性ではないこと)を確認することが重要です:traitCollection.horizontalSizeClassをpreviousTraitCollection?.horizontalSizeClassと比較します。この最適化により、フォースタッチやディスプレイスケールの変更時の不要な再描画が防止されます。
Appleデバイスによって Size Classの組み合わせは異なり、開発者はこれらの特徴を考慮する必要があります。iPhoneのポートレート — wCompact hRegular、ランドスケープ — モデルによって異なります:iPhone SE/6/7/8(wCompact hCompact)、iPhone X以降(コンテンツに応じてwCompact hCompactまたはwCompact hRegular)。iPadのフルスクリーンモード — wRegular hRegular、Split View — wCompact hRegular(画面1/3)またはwRegular hRegular(画面2/3)の場合があります。Mac Catalyst — 常にwRegular hRegular。
iPhone では、Size Classはほとんどのモデルで安定していますが、微妙な違いがあります。iPhone Plus(6+、7+、8+)とMax(X、XS、11 Pro、13–16 Pro Max)のランドスケープではwRegular hCompact — iPad miniと同様です。これにより、大きなiPhoneのランドスケープで2列にコンテンツを配置できます。iPhone SE(第1〜3世代)のランドスケープ — wCompact hCompact。ポートレートのすべてのiPhoneで垂直Size ClassはRegularですが、ランドスケープのiPhone SEではCompactです。水平はポートレートとランドスケープで常にCompactです(ランドスケープのPlus/Maxを除く)。
iPad のフルスクリーンモード — wRegular hRegularで、最大のレイアウト柔軟性を提供します。Split Viewでは動作が変わります:アプリが画面の1/3を占有する場合(Slide Overまたは1/3のSplit)、水平Size ClassはCompactになり、垂直はRegularのままです。画面2/3の場合 — wRegular hRegular。開発者はすべてのSplit Viewモードでインターフェースをテストする必要があります。Size Classは動的に変化するためです。AppleはiPadで一貫した動作を得るために、UISplitViewControllerと一緒にSize Classを使用することを推奨しています。
よくある質問
Size Class は4つの組み合わせを持つ離散システムですが、CSSブレークポイントは任意の数のポイントを持つ連続システムです。Size Classは特定の画面サイズから抽象化し、デバイスを動作でグループ化します。CSSブレークポイントはピクセルに結びついていますが、Size Classは論理的なCompact/Regularカテゴリに基づいています。
iPhone Plus/Max はランドスケープで、2列にコンテンツを表示するのに十分な画面幅があります(iPad miniと同様)。Appleは開発者が追加チェックなしでマルチカラムレイアウトを使用できるように、水平をRegularに割り当てています。これはiPhoneのCompactルールの例外です。
Size Class は実際のデバイス特性に基づいてiOSが決定し、アプリコードから変更することはできません。開発者は現在の値に反応することしかできません。システムUIはシステム要素のSize Classを上書きできますが、アプリではこれは不可能です。
SwiftUI はSize Classを直接使用しません。代わりに、開発者は@Environment(\.horizontalSizeClass)修飾子を使用して現在の値を読み取ります。SwiftUIは、アダプティブレイアウトのためのSize ClassesやLayoutプロトコルを使用したAnyLayoutなど、より高レベルのツールを提供します。
はい、Stage ManagerやSidecarを介して外部ディスプレイを接続すると、iOSはSize Classを更新します。外部モニターは通常wRegular hRegularを取得し、メイン画面は自身のSize Classを維持します。traitCollectionDidChangeは各画面のウィンドウに対して個別に呼び出されます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。