典型的なMaster-Detail構成のiPhoneアプリをiPad対応した際にやったことをご紹介します。
図の左のようにPushで遷移するiPhoneアプリがあり、iPad対応に伴い図の右のようなレイアウトを実装するケースを想定しています。
要は「どんな形でもいいからiPad対応してみたい」という人向けです。
やり方
1. UISplitViewControllerを設置
- 「master view controller」にUINavigationControllerをセット
- 「detail view controller」にDetailに対応するUIViewControllerをセット
- MasterからDetailへのSegueが「Show(e.g. Push)」だった場合、「Show Detail (e.g. Replace)」に変更
- 最初の画面ならUISplitViewControllerの「Is Initial View Controller」をチェック
Before
After
2. プロジェクトの設定
- 「Devices」を「Universal」に変更
- AppIconを再作成してiPad用の画像を設定
3. MasterViewControllerの修正
- クラスの宣言にUISplitViewControllerDelegateを追加
class MasterViewController: UITableViewController, UISplitViewControllerDelegate {
- viewDidLoadにてデリゲートの設定と、常時2ペインモードへの切り替え
override func viewDidLoad() {
super.viewDidLoad()
if let split = self.splitViewController {
split.delegate = self // デリゲートのセット
split.preferredDisplayMode = .AllVisible // 常時2ペイン表示に設定
}
}
- iPhoneで起動する際、初期画面をDetailではなくMasterの方にするために、次のメソッドを実装してtrueを返す
func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
return true
}
これで完了です。
レイアウト調整が必要になった場合
レイアウトが崩れた場合に調整します。自分がハマったところをご紹介します。
Viewのwidthの取得
例えばMasterのUIViewControllerでtableViewのwidthを取得したい場合、最初のviewWillAppearまでは全画面のwidthが返ってきてしまい、実際に表示されるときのwidthが取得できません。
どうしてもviewWillAppearまでに欲しい場合はself.splitViewController!.primaryColumnWidthを使用して取得します。
回転対応
iPad対応すると画面回転に対応したくなってきます(笑)
回転イベントはviewWillTransitionToSizeで取得できますが、回転後のナビゲーションバーやステータスバーのサイズが取得できません。この場合、coordinator.animateAlongsideTransitionに指定するブロックで取得・設定できました。(正攻法ではないかもしれません。ちなみに回転後の画面サイズだけならsizeから取得できます。)
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
coordinator.animateAlongsideTransition(
{ (context: UIViewControllerTransitionCoordinatorContext) -> Void in
let width = self.navigationController!.navigationBar.bounds.height
// レイアウト調整
}, completion: nil)
}
おわりに
iPhoneアプリのiPad対応でやったことをご紹介しました。
もし他によりよい方法がありましたらコメントいただけるとうれしいです。