Blog スタッフブログ

iOS Swift システム開発

[iOS]UIFeedbackGeneratorで触覚フィードバックを返す

Swift

こんにちは、株式会社MIXシステム開発担当のBloomです。

早速本題のUIFeedbackGeneratorで触覚フィードバックを返す方法について、

お仕事の中で得た知見を共有させていただきたいと思います。

UIFeedbackGeneratorとは

ユーザ操作をトリガーとして少し端末が振動するなど、触覚で操作感の印象を与えるために存在するAPIです。

UIKitで提供できる触覚フィードバックは4種類あり、それぞれ実装例とともに解説させていただきます。

UIImpactFeedbackGenerator

単純な振動を伝える触覚フィードバックです。styleでは振動の感じを、intensityでは強度を0.0~1.0で指定することができます。

class ViewController: UIViewController {
    @IBOutlet weak var anyButton: UIButton!
    var feedback: UIImpactFeedbackGenerator!
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if #available(iOS 17.5, *) {
            feedback = UIImpactFeedbackGenerator(style: .medium, view: self.anyButton)
        } else {
            feedback = UIImpactFeedbackGenerator(style: .medium)
        }
        // 振動再生の準備をします
        feedback.prepare()
    }
    @IBAction func buttonTouchUpInside(_ sender: Any?) {
        if #available(iOS 17.5, *) {
            feedback.impactOccurred(intensity: 1.0, at: self.anyButton.center)
        } else {
            feedback.impactOccurred()
        }
    }
}

UISelectionFeedbackGenerator

選択状態が変化したことを伝える触覚フィードバックです。ほとんどImpactFeedbackを低強度にしたものと似たような触感で、より簡素に用途を限定したものと捉えて良いでしょう。

class ViewController: UIViewController {
    @IBOutlet weak var anyButton: UIButton!
    var feedback: UISelectionFeedbackGenerator!
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if #available(iOS 17.5, *) {
            feedback = UISelectionFeedbackGenerator(view: self.anyButton)
        } else {
            feedback = UISelectionFeedbackGenerator()
        }
        // 振動再生の準備をします
        feedback.prepare()
    }
    @IBAction func buttonTouchUpInside(_ sender: Any?) {
        if #available(iOS 17.5, *) {
            feedback.selectionChanged(at: self.anyButton.center)
        } else {
            feedback.selectionChanged()
        }
    }
}

UINotificationFeedbackGenerator

操作結果を伝える触覚フィードバックです。styleをsuccess, error, warningから選択可能であり、それぞれで振動回数などが異なります。例えばerrorはiPhoneのロック解除失敗時に近いような触覚で、一般的なユーザでも触れる頻度が多いフィードバックかと思われます。

class ViewController: UIViewController {
    @IBOutlet weak var anyButton: UIButton!
    var feedback: UINotificationFeedbackGenerator!
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if #available(iOS 17.5, *) {
            feedback = UINotificationFeedbackGenerator(view: self.anyButton)
        } else {
            feedback = UINotificationFeedbackGenerator()
        }
        // 振動再生の準備をします
        feedback.prepare()
    }
    @IBAction func buttonTouchUpInside(_ sender: Any?) {
        if #available(iOS 17.5, *) {
            feedback.notificationOccurred(.warning, at: self.anyButton.center)
        } else {
            feedback.notificationOccurred(.warning)
        }
    }
}

UICanvasFeedbackGenerator

このクラスのみ趣が異なり、iOS17.5以降でしか利用することができません。また、Apple Pencil Proの利用が前提となり、Apple Pencil ProにおいてiPadへ描画操作を行った際に触覚フィードバックを提供するためのAPIとなります。iPhone環境で実装し、指で操作した場合では特に何もフィードバックは発生しないようです。

これまでのサンプルコードと同じような構文で動作しますが、基本的にはパンジェスチャとの組み合わせの相性が良いようです。公式ドキュメントにサンプルコードが掲載されているため参考にしてください。

これで簡単に触覚フィードバックを実装することができました。良かったですね。

参考文献

UIKitの新機能 – WWDC24 – ビデオ – Apple Developer

Playing haptic feedback in your app – Apple Developer Documentation