【Swift】デバイスの向き変更を検知/取得する方法!UIDeviceOrientation型

この記事からわかること

  • Xcodeアプリ画面向き変更検知する方法
  • デバイスの向き(//上向き)を取得するには?
  • UIDeviceOrientation型とは?
  • UIViewControllerviewWillTransitionメソッドの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Swift UIでデバイスの向きを取得する方法と変更を検知する方法をまとめていきたいと思います。

【Xcode】アプリ画面の向きを固定する方法!デバイスの回転と縦横識別

環境

現在の画面の向きを取得する

デバイス自体の現在の向きをコードで取得するにはUIDeviceクラスのorientationプロパティを参照します。

var orientation: UIDeviceOrientation

UIDeviceインスタンスにはシングルトンのcurrentプロパティからアクセスします。

使用例

UIDevice.current.orientation

UIDeviceOrientation型

取得できるのは列挙型UIDeviceOrientationとして定義されている値です。全部で7種類定義されており、縦向きや横向き、デバイスが水平で画面が上向きなどの状態を取得することができます。

使用例

func printOrientation(){
    
    let orientation:UIDeviceOrientation = UIDevice.current.orientation
    switch orientation{
        case .unknown:
            print("デバイスの向きが不明")
        case .portrait:
            print("デバイスの向きが縦向き")
        case .portraitUpsideDown:
            print("デバイスの向きが逆さま")
        case .landscapeLeft:
            print("デバイスの向きが左向き")
        case .landscapeRight:
            print("デバイスの向きが右向き")
        case .faceUp:
            print("デバイスが水平で画面が上向き")
        case .faceDown:
            print("デバイスが水平で画面が下向き")
        default:
            break       
    }
}

ここでいう左向き(landscapeLeft)などはホームボタンが左にあることを示しています。

デバイスの回転を制限する

デバイスが回転した際にアプリの画面を一緒に回転させたくない場合「TARGETS」>「Deployment Info」>「Device Orientation(デバイスの向き)」から設定可能です。「Device Orientation(デバイスの向き)」ではアプリに許容させたい向きを指定する設定項目なのでアプリ画面の向きを縦向きのみに固定するにはPortraitのみにチェックを入れます。

【Xcode】アプリ画面の向きを固定する方法!デバイスの回転と縦横識別

デバイスの回転を検知する

デバイスの回転を検知するためにはNotificationCenterクラスを使用します。NotificationCenterクラスは異なるクラス間でイベントを通知するための機能を実装できるクラスです。デバイスの回転した際にイベント通知を受け取り、任意の処理を行わせることが可能になります。

observerOrientationメソッドの引数forNameUIDevice.orientationDidChangeNotificationを渡すことでデバイスの回転を観測し、通知として受け取ることが可能です。

func observerOrientation(){
    NotificationCenter.default.addObserver(
        forName: UIDevice.orientationDidChangeNotification,
        object: nil,
        queue: nil) { orientation in
             print(type(of: orientation)) // Notification
            print("デバイスの向きが変わったよ")
        }
}

これでデバイスの回転を検知することができるようになりました。しかしorientationで受け取れる値はNotification型であり、縦向き/横向きで識別することはできませんでした。

UIDevice.beginGeneratingDeviceOrientationNotifications

公式リファレンス:beginGeneratingDeviceOrientationNotificationsメソッド

UIDeviceクラスにはbeginGeneratingDeviceOrientationNotificationsメソッドなるものが用意されています。これはデバイスの向きの変更に関する通知の生成を開始する役割を持っているメソッドです。また逆の役割(デバイスの向きの変更に関する通知の生成を終了)を持つendGeneratingDeviceOrientationNotificationsメソッドも用意されています。

addObserverメソッドで既にイベントを検知できていますが、公式リファレンスを読むとこの2つのメソッドを適切なタイミングで正しく呼び出すのが正しいのかもしれません。

func observerOrientation(){
    UIDevice.current.beginGeneratingDeviceOrientationNotifications()
    NotificationCenter.default.addObserver(
        forName: UIDevice.orientationDidChangeNotification,
        object: nil,
        queue: nil) { orientation in
            print(type(of: orientation)) // Notification
            print("デバイスの向きが変わったよ")
        }
}

func stopObserver(){
    UIDevice.current.endGeneratingDeviceOrientationNotifications()
}

実際に観測を開始してからendGeneratingDeviceOrientationNotificationsを実行するとイベントは検知されなくなります。

UIKItでデバイスの回転を検知する

公式リファレンス:viewWillTransition

UIKitのUIViewControllerクラスでビューのサイズが変更されていることを検知できるviewWillTransitionメソッドを使用してビューの回転を検知することが可能です。

デバイスの向きはview.window?.windowScene!.interfaceOrientationから取得することが可能です。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    
    coordinator.animate(alongsideTransition: { (context) in
        // iOS12以前
        // let newOrientation = UIApplication.shared.statusBarOrientation
        // iOS13以降
        guard let newOrientation = self.view.window?.windowScene!.interfaceOrientation else { return }
        
        if newOrientation.isLandscape {
            print("横向き")
        } else if newOrientation.isPortrait {
            print("縦向き")
        }
    }) { (context) in
        // 画面の向きが変わった後の処理をここに追加
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index