【Swift】端末の揺れを取得する

2022.01.06

SMAPさんのSHAKEを聴いていると、iPhoneがシェイクされたかどうかを検知する方法を無性に知りたくなったので調べることにしました。

環境

  • Xcode 13.2.1
  • iOS 15.2

端末の揺れを取得する

端末の揺れを取得する方法としてCoreMotionを用いてデバイスの加速度センサーの値の変化から揺れを推測するという方法もありますが、今回はUIKitmotionBeganmotionEndedmotionCancelledメソッドを用いて揺れを取得することにしました。

サンプルコード

class ViewController: UIViewController {

    @IBOutlet private weak var shakeLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        becomeFirstResponder()
    }

    override var canBecomeFirstResponder: Bool {
        return true
    }

    @IBOutlet private weak var shakeLabel: UILabel!

    override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            // 揺れが開始した時の処理
            shakeLabel.text! += "開始\n"
        }
    }

    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            // 揺れが終了した時の処理
            shakeLabel.text! += "終了\n"
        }
    }

    override func motionCancelled(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            // 揺れがキャンセルした時の処理
            shakeLabel.text! += "キャンセル\n"
        }
    }
}

motionが開始した時、終了した時、キャンセルした時にEventSubtype.motionShakeなら処理を行う内容になります。

UIEvent.EventSubtype.motionShake

ユーザーがデバイスを振っているかどうかのイベントになります。

各処理が呼ばれるタイミング

motionBegan(_:with:)

motionが開始した時に呼ばれます

motionEnded(_:with:)

motionが終了した時に呼ばれます

motionCancelled(_:with:)

motionがキャンセルされた時に呼ばれます。

motionCancelled(_:with:)のメソッドが呼び出されるタイミングについて、公式ドキュメントに下記の記述がありました。

キャンセルとは、アプリケーションを非アクティブにしたり、モーションイベントを処理するビューをウィンドウから削除したりするものです。揺れが長すぎる場合、UIKitはこのメソッドを呼び出すこともあります。

また、ドキュメントにはモーションイベントを処理するすべてのレスポンダーは、このメソッドを実装する必要がありますと記載されており、キャンセルされた時のハンドリングも行った方が良さそうです。

becomeFirstResponder

今回作成しているサンプルアプリでは、他でmotionを処理するレスポンダーがない為、becomeFirstResponderを呼ばなくても意図した動作を行いますが、利用するライブラリやコードの構成によって想定外の動きをすることも考えられるので必ず処理を行いたい場合は、becomeFirstResponderを実行し、canBecomeFirstResponderの値をtrueで上書きしておいた方が良さそうです。

実機で動作を確認する

実際でサンプルコードの動きを確認してみましょう。

揺れが開始した後、揺れが長すぎて揺れの終了が取得できない場合はキャンセルが呼ばれているのが分かると思います。

揺れをシュミレーターで確認する

実機だけではなくシュミレーターでも揺れを取得することが出来ます。

Simulator > Device > Shake を押すことでシュミレーター上でも擬似的に揺れを発生させることが出来ます。

Shakeを押すと、motionBeganmotionEndedが呼ばれます。

せっかくなので

端末を振ると、シェイク・シェイク・ブギーなテキストが表示されるアプリを作ってみました。

おわりに

これで心置きなくSHAKEを聴けそうです。

チョーベリベリ最高。

参考