HapticFeedback実装の目的とかUI/UX観点
- ユーザーの“操作感”はアプリの印象を左右する
- Haptic Feedback(触覚フィードバック)を入れるだけで「押した感」が伝わる
- でも毎回Generator書くのは地味にだるい
- なので、Singletonで一括管理する
HapticFeedback.swift
を作っておく
なぜSingletonなのか
- パフォーマンス面(
prepare()
の意味) - アプリ全体で状態共有不要 → Singleton向き
- UI操作は頻繁かつ即応性が求められる → 毎回生成NG
- SwiftUIと組み合わせても安定動作
実装 (HapticFeedback.swift)
import UIKit
final class HapticFeedback {
static let shared = HapticFeedback()
private let impactGenerators: [UIImpactFeedbackGenerator.FeedbackStyle: UIImpactFeedbackGenerator] = [
.light: UIImpactFeedbackGenerator(style: .light),
.medium: UIImpactFeedbackGenerator(style: .medium),
.heavy: UIImpactFeedbackGenerator(style: .heavy),
.soft: UIImpactFeedbackGenerator(style: .soft),
.rigid: UIImpactFeedbackGenerator(style: .rigid)
]
private let selectionGenerator = UISelectionFeedbackGenerator()
private let notificationGenerator = UINotificationFeedbackGenerator()
private init() {}
func impact(_ style: UIImpactFeedbackGenerator.FeedbackStyle) {
guard let generator = impactGenerators[style] else { return }
generator.prepare()
generator.impactOccurred()
}
func selection() {
selectionGenerator.prepare()
selectionGenerator.selectionChanged()
}
func notification(_ type: UINotificationFeedbackGenerator.FeedbackType) {
notificationGenerator.prepare()
notificationGenerator.notificationOccurred(type)
}
}
使い方
UIKit
ButtonActionとかにそのまま入れる
HapticFeedback.shared.impact(.medium)
HapticFeedback.shared.notification(.success)
SwiftUI
同じく
Button("タップ") {
HapticFeedback.shared.selection()
}
View拡張すると、↓みたいに使える。
Button("HAPTIC!") {
print("Hapticだぜ")
}
.hapticTap(.heavy)
extension View {
func hapticTap(_ style: UIImpactFeedbackGenerator.FeedbackStyle) -> some View {
self.onTapGesture {
HapticFeedback.shared.impact(style)
}
}
}