[iOS] UIDevice.current.orientation が unknown を返す時の対応方法

iOS デバイスの画面方向をチェックするための UIDevice.current.orientation が unknown を返す時の対応方法

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Monterery beta 3
  • Xcode 13 beta3
  • iOS 15 beta

画面/デバイスの向き

iOS デバイスの画面の向きを確認するための仕組みとして、UIDevice.current.orientation があります。

画面の向きの種類等は、以下の記事を参照ください。
SwiftUI[SwiftUI] 縦横に柔軟に配置するレイアウトを作る

UIDevice.current.orientation が unknown 返す?!

UIDevice.current.orientation が unknown を返すケースがあります。加速度センサー等で検知できない時だそうです。

はまったケースは、
”Landscape にして起動したアプリで 起動直後は Landscape として正しい値が取得できるのに、そこから 別ビューを表示するために orientation をチェックすると unknown が返されてしまう” というケースでした。

画面のレイアウト調整に使用するために取得しているので、取得するタイミングを後回しにはできず、延々と調べてました。

unknown が返される時の workaround

(iOS14 以降では使えないのですが)回避策が見つかりましたので、メモしておきます。

UIApplication.shared.statusBarOrientation

(画面の向きではなく)アプリのインターフェースの向きをつかった判別も可能ということで、


UIApplication.shared.statusBarOrientation.isLandscape

というようなコードを使っても判別できたようです。

残念ながら、iOS13 で statusBarOrientation というプロパティが deprecated になってしまいました。

UIScreen.main.bounds

途方に暮れていたのですが、ベタな方法で判断してみることにしました。

デバイスのスクリーンは、UIScreen.main 経由でアクセスできるはずなので、UIScreen.main.bounds で画面の大きさが取得できるはずです。

ということで、UIDevice.current.orientation から unknown が返された時に、以下のように追加情報で判定することにしてみました。


// 前提:orientation は、UIDeviceOrientation 型で定義された変数で、
// この変数をみて、以降でレイアウト調整が行われます。

if UIDevice.current.orientation.isValidInterfaceOrientation {
    orientation = UIDevice.current.orientation
} else {
    // calc orientation from UIScreen.main.bounds.size (backup for UIDevice.current.orientation returns unknown)
    orientation = UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height ? UIDeviceOrientation.landscapeLeft : UIDeviceOrientation.portrait
}

本来 landscape にも、landscapeLeft や landscapeRight があり、portrait にも、portrait と portraitUpsideDown がありますが、背に腹は変えられないということで、それぞれ landscapeLeft と portrait を決め打ちしてしまっています。

上記の制限はありますが、それ以外は、うまく動作しています。

もともと、自分の環境では、起動直後の特定のタイミングのみ unknown が返される状況でしたので、ほとんど UIDevice.current.orientation を使って処理されているので、本当に fallback 実装的な意味合いが強いです。

まとめ:UIDevice.current.orientation が unknown を返す時の対応方法

UIDevice.current.orientation が unknown を返す時の対応方法
  • iOS13以前であれば、UIApplication.shared.statusBarOrientation を使用する
  • UIScreen.main.bounds の size をみて判断する

安定して取得できる方法をご存知の方は教えてください。

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です