iOSでの各回転検知方法とその結果


iOSで回転検知方法が複数あり、用途によっては向き不向きがあるようなので、回転検知方法と検知タイミングごとの結果をまとめてみました。

検証時環境

開発環境:Xcode9beta
iOSバージョン:11beta
言語:Swift4

端末の縦横状態取得

端末の縦横状態は以下の2種類で取得しました。

UIInterfaceOrientation
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation))
let isLandscape = UIInterfaceOrientationIsLandscape(UIApplication.shared.statusBarOrientation))
UIDeviceOrientation
let isPortrait = UIDeviceOrientationIsPortrait(UIDevice.current.orientation))
let isLandscape = UIDeviceOrientationIsLandscape(UIDevice.current.orientation))

回転検知方法

viewDidLoad


アプリ起動直後を想定した結果です。
- UIInterfaceOrientationとの組み合わせのみ検知は正確

NSNotification

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.onOrientationDidChange(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}

@objc
func onOrientationDidChange(notification: NSNotification) {
    // ここに回転時の処理
}


- 検知は正確
- アプリ起動直後に処理される
- バックグラウンド移行後2回処理される
- ViewControllerが重なった状態でも検知される

viewWillLayoutSubviews


- 検知は正確
- ViewControllerが重なった状態では検知されない

viewDidLayoutSubviews

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // ここに回転時の処理
}


- 検知は正確
- ViewControllerが重なった状態では検知されない

viewWillTransition

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
    // ここに回転時の処理
}


- UIDeviceOrientationとの組み合わせのみ検知は正確
- 回転時のみ処理される
- ViewControllerが重なった状態では検知される

予定

  • ViewControllerが重なっている状態での検知結果を追加予定
  • CollectionViewの各処理タイミングと回転検知タイミングを追加予定