LoginSignup
5
5

More than 5 years have passed since last update.

iPadの縦置きと横置きでレイアウトを切り替える

Posted at

iOSのアプリ開発では、Size Classを使って1つのStory boardでiPhoneやiPadの画面サイズに応じて異なるレイアウトを作成することができるようになりました。
Size Classは2018年5月現在、以下のように定義されています。

w:compact w:regular
h:compact iPhone(横置き) iPhone Plus(横置き)
h:regular iPhone(縦置き) iPad(縦置き/横置き)

参考 https://developer.apple.com/ios/human-interface-guidelines/visual-design/adaptivity-and-layout/

ここで問題になるのは、iPadは縦置き(portrait)も横置き(landscape)もwidth = regular, height = regularに割り当てられているので、縦置きと横置きでレイアウトを変えることができないということです。

これを以下のような割り当てに変えて、iPadの縦置きと横置きで異なるSize Classにする方法がわかったので書き残しておきます。

w:compact w:regular
h:compact iPhone(横置き) iPhone Plus(横置き)、iPad(横置き)
h:regular iPhone(縦置き) iPad(縦置き)

ただし、見てわかるようにiPhone Plus(横置き)とiPad(横置き)は同じSize Classが割り当たるので、同じレイアウトになってしまいます。

手順は以下の通りです。

  1. 対象となる画面にContainer Viewを配置する。この画面のView ControllerをContainerViewControllerとします。

  2. Container Viewに組み込まれたView(自動的にセグエで接続されているView)に表示したい内容を配置します。上記のSize Classに応じてレイアウトが変わるように作成してください。このView ControllerをMyViewControllerとします

  3. ContainerViewControllerに以下の実装を行います。

ContainerViewController.swift
class ContainerViewController.swift: UIViewController {
    let traitCollectionsRC = UITraitCollection(traitsFrom: [UITraitCollection(horizontalSizeClass: .regular), UITraitCollection(verticalSizeClass: .compact)])

    // 初期表示用
    override func viewDidLoad() {
        super.viewDidLoad()
        setChildTrait(size: CGSize(width: self.view.bounds.width, height: self.view.bounds.height))
    }

    // 回転後用
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        setChildTrait(size: size)
    }

    func setChildTrait(size: CGSize) {
        if ( self.traitCollection.horizontalSizeClass == .regular && self.traitCollection.verticalSizeClass == .regular ) {
            // 両方ともregularの場合をiPadだと判断
            if size.width > size.height {
                // 幅の方が大きい場合は横置きだと判断し、w:regular,h:compactで上書きする
                // なおchildViewController[0]がMyViewControllerになっている 
                self.setOverrideTraitCollection(traitCollectionsRC, forChildViewController: self.childViewControllers[0])
            } else {
                // それ以外の場合は縦置きになっているので上書きをnilで解除
                // 上書きしなければ、本来のw:regular, h:regularが適用される
                self.setOverrideTraitCollection(nil, forChildViewController: self.childViewControllers[0])
            }
        }
    }
}

Container Viewを経由する必要があるので若干面倒ですが、これでiPad縦置きと横置きのレイアウトをSize Classで変えることができるようになります。

環境

  • Xcode 9
  • Swift 4
  • iOS 11.3
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5