【Swift】触覚フィードバック(HapticFeedback)を使う
はじめに
触覚フィードバック (Haptic Feedback
) を実装する機会があったのでその備忘録として本記事を書きました。
触覚フィードバックとは
Apple Developper Design / Playing haptics
ざっくり言うと iPhone でアプリを使用していて振動するアレのことです。
iOS アプリではUISwitch
, UIPickerView
がデフォルトで触覚フィードバックが再生されます。
ベストプラクティス
一貫性を持って使用すること
Use haptics consistently. It’s important to build a clear, causal relationship between each haptic and the action that causes it so people learn to associate certain haptic patterns with certain experiences. If a haptic doesn’t reinforce a cause-and-effect relationship, it can be confusing and seem gratuitous. For example, if your app plays a specific haptic pattern when a game character fails to finish a mission, people associate that pattern with a negative outcome. If you use the same haptic pattern for a positive outcome like a level completion, people will be confused.
Apple Developper / Design / Pattern / Playing haptics
ある動作が成功した時のフィードバックと失敗した時のフィードバックの種類を同じにすると、ユーザーが混乱するので種類を分けましょう
触覚フィードバックのタイミングを合わせること
Use haptics in ways that complement other feedback in your app. When visual, auditory, and tactile feedback are in harmony — as they generally are in the physical world — the user experience is more coherent and can seem more natural. For example, match the intensity and sharpness of a haptic with the animation you use to accompany it. You can also synchronize sound with haptics; for developer guidance, see Delivering rich app experiences with haptics. Apple Developper / Design / Pattern / Playing haptics
View の表示、アニメーション、サウンドなどと触覚フィードバックを合わせて使用する場合、タイミングを合わせましょう
使用頻度に注意すること
Avoid overusing haptics. Sometimes a haptic can feel just right when it happens occasionally, but become tiresome when it plays frequently. It’s important to do user testing that can help you discover a balance that most people appreciate. Often, the best haptic experience is one that people may not be conscious of, but miss when it’s turned off.
Apple Developper / Design / Pattern / Playing haptics
ユーザーが疲れてしまうため、あまり頻繁にフィードバックを再生させるのは避けましょう
オプションとして使用すること
Make haptics optional. Let people turn off or mute haptics if they wish, and make sure people can still enjoy your app without them.
Apple Developper / Design / Pattern / Playing haptics
触覚フィードバックはさらなるオプションとして、まずは使用せずともユーザーが満足できるアプリを作成しましょう
物理的な影響を考慮すること
Be aware that playing haptics might impact other user experiences. By design, haptics produce enough physical force for people to feel the vibration. Ensure that haptic vibrations don’t disrupt user experiences involving the camera, gyroscope, or microphone.
Apple Developper / Design / Pattern / Playing haptics
カメラ、ジャイロスコープ、マイクを使用している場合に触覚フィードバックの振動が悪影響を及ぼさないか確認しましょう
触覚フィードバック(HapticFeedback)の使用方法
動作環境
- Xcode 13.4.1
- Swift 5.6.1
- iOS 15.4.1
- iPhone 13
Haptic Feedback の種類
UIImpactFeedback
1. var generator: UIImpactFeedbackGenerator?
generator = UIImpactFeedbackGenerator(style: .light)
generator?.prepare()
generator?.impactOccurred()
generator = nil
視覚体験を補完するための触覚フィードバック
UIImpactFeedback
の種類
- Light
- Medium
- Heavy
- Rigid
- Soft
ここで UIImpactFeedback のサンプルを再生できます
UINotificationFeedback
2. var generator: UINotificationFeedbackGenerator?
generator = UINotificationFeedbackGenerator()
generator?.prepare()
generator?.notificationOccurred(type: .success)
generator = nil
タスクまたはアクションの結果に関する触覚フィードバック
UINotificationFeedback
の種類
- Success
- タスクやアクションが成功したとき
- Warning
- タスクやアクションが警告を生成したとき
- Error
- タスクやアクションがエラーを起こしたとき
ここで UINotificationFeedback のサンプルを再生できます
UISelectionFeedback
3. 使用例があまりピンと来なかったので今回は割愛します
よく使用されているケースなどがあれば教えてください 🙇
便利なサンプルコード
enum ImpactFeedbackStyle: Int {
case light
case medium
case heavy
case soft
case rigid
var value: UIImpactFeedbackGenerator.FeedbackStyle {
return .init(rawValue: rawValue)!
}
}
enum NotificationFeedbackType: Int {
case success
case failure
case error
var value: UINotificationFeedbackGenerator.FeedbackType {
return .init(rawValue: rawValue)!
}
}
enum Haptic {
case impact(_ style: ImpactFeedbackStyle, intensity: CGFloat? = nil)
case notification(_ type: NotificationFeedbackType)
}
final class HapticFeedbackManager {
static let shared = HapticFeedbackManager()
private init() {}
private var impactFeedbackGenerator: UIImpactFeedbackGenerator?
private var notificationFeedbackGenerator: UINotificationFeedbackGenerator?
func play(_ haptic: Haptic) {
switch haptic {
case .impact(let style, let intensity):
impactFeedbackGenerator = UIImpactFeedbackGenerator(style: style.value)
impactFeedbackGenerator?.prepare()
if let intensity = intensity {
impactFeedbackGenerator?.impactOccurred(intensity: intensity)
} else {
impactFeedbackGenerator?.impactOccurred()
}
impactFeedbackGenerator = nil
case .notification(let type):
notificationFeedbackGenerator = UINotificationFeedbackGenerator()
notificationFeedbackGenerator?.prepare()
notificationFeedbackGenerator?.notificationOccurred(type.value)
notificationFeedbackGenerator = nil
}
}
HapticFeedbackManager.shared.play(.impact(.heavy))
impactOccurred(intensity: CGFloat)
のintensity
には 0.0 ~ 1.0 までの値で振動の強度を調節することができるみたいです。ただ、実機で試したところ恐らくデフォルトが 1.0 なのでデフォルトよりも弱めたいときに使用するっぽいです 🤔
参考サイト
Apple Developper / Design / Pattern / Playing haptics
Documentation / UIKit / Animation and Haptics / UIFeedbackGenerator
Discussion