【Swift】端末をバイブさせる
ユーザーがあるアクションを実行した時に端末をバイブさせて触覚的に知らせたかったので調べてみました。
環境
- Xcode 13.3
- iPhone 12mini
- iOS 15.4.1
デバイスを振動させるには、UIFeedbackGenerator
のサブクラスを使用し触覚フィードバック振動させる方法とAudioToolbox
を使用した振動方法があります。
UIFeedbackGenerator
UIFeedbackGenerator
のサブクラスには、以下の三つがあります。
- UIImpactFeedbackGenerator
- UISelectionFeedbackGenerator
- UINotificationFeedbackGenerator
UIImpactFeedbackGenerator
物理的な影響をシミュレートする触覚を作成するジェネレータです。アプリ上で衝撃を表現するのに活用出来ます。
使用方法は簡単でフィードバックジェネレータのインスタンス生成をして、impactOccurred()
を呼ぶと衝撃の触覚を感じれます。
let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy) feedbackGenerator.impactOccurred()
UIImpactFeedbackGenerator
の初期化時に、UIImpactFeedbackGenerator.FeedbackStyle
を引数で渡してスタイルを決定します。
UIImpactFeedbackGenerator.FeedbackStyle
- case heavy
- 大きくて重たいユーザーインターフェイス要素の衝突
- case light
- 小さくて軽いユーザーインターフェイス要素の衝突
- case medium
- 普通サイズのユーザーインターフェイス要素の衝突
- case rigid
- iOS 13から追加されているものでドキュメントの内容は空だが、名前から推測するには堅い衝突のフィードバックに適していそう
- case soft
- iOS 13から追加されているものでドキュメントの内容は空だが、名前から推測するにはソフトな衝突のフィードバックに適していそう
impactOccurred
インパクトが発生したことをジェネレータに通知し、ジェネレータはスタイルの値に基づいて適切な触覚を再生します。impactOccurred
ではなく、impactOccurred(intensity:)
を使用すれば衝撃の強度も調節することが出来ます。
使ってみた感想
動画や文章では振動具合が上手にお伝えできませんが、インパクトという名前から想像していたものとは違ってFeedbackStyleを.heavy
にした場合で振動を発生させた場合でも個人的にはあまり強くない、伝わりにくいなと感じました。
UISelectionFeedbackGenerator
選択の変更を示す触覚を作成するジェネレータです。
特にFeedbackStyleや強度の調整も無い為、使い方はシンプルです。
let feedbackGenerator = UISelectionFeedbackGenerator() feedbackGenerator.selectionChanged()
使ってみた感想
本当に一瞬、「コツ」という触覚を伝えてくれます。
UINotificationFeedbackGenerator
成功、失敗、および警告を伝達するための触覚を作成するジェネレータです。ユーザーがあるアクションを実行した時に端末をバイブさせて触覚的に知らせたいという今回やりたい事と一番合っていそうです。
フィードバックジェネレータのインスタンス生成して、notificationOccurred(_:)
の引数にUINotificationFeedbackGenerator.FeedbackType
を渡してフィードバックを発生させます。
let feedbackGenerator = UINotificationFeedbackGenerator() feedbackGenerator.notificationOccurred(.success)
UINotificationFeedbackGenerator.FeedbackType
FeedbackTypeには失敗、成功、警告を表す3タイプがあります。
- case error
- タスクが失敗したことを示す通知フィードバックタイプ。
- case success
- タスクが正常に完了したことを示す通知フィードバックタイプ。
- case warning
- タスクが警告を生成したことを示す通知フィードバックタイプ。
使ってみた感想
自分の感覚が鈍いせいか、.error
と.success
の違いがあまり分からなかった。.warning
はその二つよりもやや振動が少ない印象
UIFeedbackGeneratorは設定に左右される
紹介したUIFeedbackGenerator
のサブクラスですが、設定 > サウンドと触覚 > システムの触覚 をオフにすると振動が発生しなくなります。必ず振動させてユーザーに伝えたいという時には使わない方が良さそうです。
prepare(オプション)
今回は、prepare()
を使用していませんが、UIFeedbackGenerator
のインスタンス生成後に、prepare()
を使用することがドキュメントで推奨されていました。
prepare()メソッドの使用は任意ですが、強く使用を推奨します。このメソッドを呼び出すとフィードバックのレイテンシーが可能な限り低ります。
下記のようにprepare()
を呼び出してすぐにフィードバックを発生するような場合では、遅延は改善されないようです。
let feedbackGenerator = UINotificationFeedbackGenerator() feedbackGenerator.prepare() feedbackGenerator.notificationOccurred(.warning)
UIFeedbackGeneratorの解放(オプション)
準備されたジェネレーターが不要になった場合は、ジェネレーターオブジェクトへのすべての参照を削除し、システムに割り当てを解除させます。これにより、TapticEngineはアイドル状態に戻ります。
var feedbackGenerator: UINotificationFeedbackGenerator? = UINotificationFeedbackGenerator() feedbackGenerator?.prepare() feedbackGenerator?.notificationOccurred(.success) feedbackGenerator = nil
インスタンス変数にnil
を代入すると、古いジェネレーターへの参照が削除されます。
TapticEngine
Tapticエンジンはバイブレーターに代わって採用された振動装置で、通常のバイブレータのモーターによる回転と異なり、磁石でウエイトを左右に動かすことで、「コツコツ」という振動を発生させている。
UIFeedbackGenerator
によるフィードバック振動はバイブレータによる振動とは異なる種類の振動で明らかな振動を伝える用途には向いてなさそうですね。
AudioToolBoxを使って分かりやすく振動させる
UIFeedbackGenerator
によるフィードバック振動ではなく、明らかなバイブレーションをさせるならAudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
を使用します。
AudioToolBox
をインポートし、
import AudioToolbox
バイブを行いたい箇所で、AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
を呼び出すだけです。
// 例 @IBAction private func vibrateDevice() { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) }
この方法だと、設定でシステムの触覚をオフにしても振動させることが出来ます。ただし、ドキュメントに記載してありますが、iPod Touchでは振動しないようです。
SystemSoundID
SystemSoundIDで選択出来るバイブレーションの種類は他にもあります。AudioServices(非公式)でカテゴリがVibrateとなっているIDをAudioServicesPlaySystemSound(_:)
の引数で入力してみてお気に入りの振動を見つけてみてください。
公式のSystemSoundIDのリストを見つけれなかったのですが、こちらの記事を見てみると上記リスト以外のIDで利用出来るものが他にもあるようです。
おわりに
触覚フィードバック振動を使う方法と、バイブレータによる振動を使用する方法を学びました。それぞれに決まった用途があるのでそれに合わせて使っていきたいと思います。