Reusable HapticManager
One shared object that prepares generators once and exposes every standard haptic as a single call.
import UIKit
/// Central access point for standard haptics.
/// Call `HapticManager.shared.prepare()` shortly before an interaction
/// (e.g. when a screen appears) so the Taptic Engine is spun up.
final class HapticManager {
static let shared = HapticManager()
private let lightImpact = UIImpactFeedbackGenerator(style: .light)
private let mediumImpact = UIImpactFeedbackGenerator(style: .medium)
private let heavyImpact = UIImpactFeedbackGenerator(style: .heavy)
private let softImpact = UIImpactFeedbackGenerator(style: .soft)
private let rigidImpact = UIImpactFeedbackGenerator(style: .rigid)
private let selection = UISelectionFeedbackGenerator()
private let notification = UINotificationFeedbackGenerator()
private init() {}
/// Wakes the Taptic Engine to remove first-hit latency.
func prepare() {
lightImpact.prepare()
selection.prepare()
notification.prepare()
}
// MARK: Impacts (physical collisions: taps, snaps, drops)
func tapLight(intensity: CGFloat = 1.0) { lightImpact.impactOccurred(intensity: intensity) }
func tapMedium(intensity: CGFloat = 1.0) { mediumImpact.impactOccurred(intensity: intensity) }
func tapHeavy(intensity: CGFloat = 1.0) { heavyImpact.impactOccurred(intensity: intensity) }
func tapSoft() { softImpact.impactOccurred() } // rounded, muffled
func tapRigid() { rigidImpact.impactOccurred() } // sharp, precise
// MARK: Selection (ticks while values change)
func selectionChanged() { selection.selectionChanged() }
// MARK: Notifications (outcomes)
func success() { notification.notificationOccurred(.success) }
func warning() { notification.notificationOccurred(.warning) }
func error() { notification.notificationOccurred(.error) }
}
// Usage anywhere in the app:
// HapticManager.shared.tapLight()
// HapticManager.shared.success()