SwiftでUISplitViewControllerのカラム幅を調整する
UISplitViewController のカラム幅はデフォルトではシステムが自動決定しますが、アプリの用途によってはマスター側をもっと広くしたい、あるいはディテール側に最大限のスペースを確保したいという場面が出てきます。カラム幅の調整には 3 つのプロパティが関わっており、それぞれの役割を理解することで柔軟なレイアウトが可能になります。
カラム幅を制御する 3 つのプロパティ
UISplitViewController には、プライマリカラムの幅を制御するためのプロパティが 3 つ用意されています。
| プロパティ | 説明 |
|---|---|
| preferredPrimaryColumnWidthFraction | 画面幅に対する割合(0.0〜1.0) |
| minimumPrimaryColumnWidth | 最小幅(ポイント単位) |
| maximumPrimaryColumnWidth | 最大幅(ポイント単位) |
これらは互いに連携して動作します。fraction で指定した割合が minimum と maximum の範囲を超える場合は、自動的にクランプされます。最終的に確定した幅は、読み取り専用の primaryColumnWidth プロパティで確認できます。
割合指定による基本的な幅調整
もっともシンプルなのは、preferredPrimaryColumnWidthFraction を設定する方法です。
let split = UISplitViewController()
split.viewControllers = [masterNav, detailNav]
split.preferredDisplayMode = .oneBesideSecondary
split.preferredPrimaryColumnWidthFraction = 0.40.4 を指定すると、画面幅の 40% がプライマリカラムに割り当てられます。iPad Pro 12.9 インチの横向き(幅 1366 ポイント)であれば約 546 ポイント、iPad Air の横向き(幅 1180 ポイント)であれば約 472 ポイントになる計算です。
デフォルト値は UISplitViewController.automaticDimension で、この場合システムが端末や向きに応じて適切な幅を決定します。
// デフォルトに戻したい場合
split.preferredPrimaryColumnWidthFraction =
UISplitViewController.automaticDimension最小幅と最大幅の設定
割合指定だけでは、端末によって極端に狭くなったり広くなったりする場合があります。これを防ぐために、ポイント単位で下限と上限を設定します。
let split = UISplitViewController()
split.viewControllers = [masterNav, detailNav]
split.preferredDisplayMode = .oneBesideSecondary
split.preferredPrimaryColumnWidthFraction = 0.35
split.minimumPrimaryColumnWidth = 280
split.maximumPrimaryColumnWidth = 400fraction で画面幅の 35% を希望
算出された幅が 280 未満なら 280 に引き上げ
400 を超えていたら 400 に切り詰め
最終的な幅が primaryColumnWidth に反映
この仕組みにより、どの iPad モデルでもプライマリカラムが読みやすい幅に収まるよう保証できます。メールアプリのように一覧にある程度の幅が必要で、かつディテール側も圧迫したくないケースでは、この 3 つのプロパティを組み合わせて使うのが定石です。
実際の幅を確認する
設定した値が最終的にどう解決されたかは、primaryColumnWidth で確認できます。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let split = splitViewController {
print("確定幅: \(split.primaryColumnWidth)")
}
}viewDidLayoutSubviews のタイミングで取得するのがポイントです。viewDidLoad の時点ではまだレイアウトが確定していないため、正確な値が返らない場合があります。
iOS 14 以降のカラムベース API での幅調整
iOS 14 で導入された UISplitViewController(style:) を使っている場合は、setViewController で登録したカラムごとに幅を制御します。プロパティ名は同じですが、3 カラム構成(.tripleColumn)のときはサプリメンタリカラムの幅も調整対象になります。
let split = UISplitViewController(style: .doubleColumn)
split.setViewController(masterNav, for: .primary)
split.setViewController(detailNav, for: .secondary)
split.preferredPrimaryColumnWidthFraction = 0.35
split.minimumPrimaryColumnWidth = 280
split.maximumPrimaryColumnWidth = 400
split.preferredDisplayMode = .oneBesideSecondary
split.preferredSplitBehavior = .tiledoubleColumn の場合、従来の API とプロパティは共通です。違いが出るのは tripleColumn を使ったときで、supplementary カラム用の幅プロパティが追加されます。
| プロパティ | 対象 |
|---|---|
| preferredPrimaryColumnWidthFraction | プライマリ |
| preferredSupplementaryColumnWidthFraction | サプリメンタリ |
let split = UISplitViewController(style: .tripleColumn)
split.setViewController(sidebarNav, for: .primary)
split.setViewController(listNav, for: .supplementary)
split.setViewController(detailNav, for: .secondary)
split.preferredPrimaryColumnWidthFraction = 0.2
split.minimumPrimaryColumnWidth = 200
split.maximumPrimaryColumnWidth = 260
split.preferredSupplementaryColumnWidthFraction = 0.25
split.minimumSupplementaryColumnWidth = 280
split.maximumSupplementaryColumnWidth = 3603 カラム構成の場合、プライマリ(サイドバー)は狭めに、サプリメンタリ(一覧)はやや広めに設定すると、iPad の画面幅を有効に活用できます。
splitBehavior による幅への影響
カラム幅の見え方は、preferredSplitBehavior の設定によっても変わります。
プライマリとセカンダリが画面幅を分け合う。プライマリの幅がそのままセカンダリの表示領域を圧迫するため、fraction の設定がレイアウト全体のバランスに直結する。
プライマリがセカンダリの上に重なる。セカンダリは常にフル幅で描画されるため、プライマリの幅を広めに取ってもディテール側のレイアウトが崩れにくい。
overlay モードではプライマリの幅を大きくしてもセカンダリに影響しないため、ファイルブラウザのようにマスター側の情報量が多いアプリでは overlay との組み合わせが有効です。一方、メールアプリのように常時 2 カラムを見比べたい場合は tile にして fraction を慎重に調整することになります。
回転・マルチタスク時の挙動
iPad で端末を回転させたり、マルチタスクで画面幅が変わったりすると、fraction に基づいてカラム幅が再計算されます。
override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
// 回転アニメーション中にレイアウトを調整
}) { _ in
if let split = self.splitViewController {
print("回転後の幅: \(split.primaryColumnWidth)")
}
}
}注意が必要なのは、fraction を固定していても実際の幅はポイント単位で変動するという点です。プライマリカラム内のコンテンツが特定の幅を前提としている場合、Auto Layout の制約が適切に設定されていないとレイアウト崩れの原因になります。
プライマリ内のビューは固定幅ではなく、leading / trailing の制約で親ビューに追従させる。テーブルビューやコレクションビューであればセルの自己サイズ調整が効くため、カラム幅の変動に自然に対応できる。
カスタムビューで固定幅の要素を配置している場合、primaryColumnWidth の変化を監視して明示的にサイズを更新する必要がある。viewDidLayoutSubviews で現在の幅を取得し、制約の constant を書き換えるアプローチが確実。
カラム幅の調整は見た目だけの問題に思えますが、ユーザーが情報をどれだけ快適に一覧できるかに直結します。アプリが扱うコンテンツの性質に合わせて、fraction・minimum・maximum の 3 つを丁寧に設定することで、どの iPad モデルでもバランスの良い画面分割を実現できます。