Working with Haptic Feedback
1. Using UIImpactFeedbackGenerator
| Property | Value | Description |
|---|---|---|
| impactFeedbackGenerator | UIImpactFeedbackGenerator(style: .medium) |
Initializes the feedback generator with a specific impact style |
| style | .light, .medium, .heavy |
Defines the intensity of the haptic feedback |
Example: Triggering Impact Feedback
import UIKit
class ViewController: UIViewController {
let impactFeedbackGenerator = UIImpactFeedbackGenerator(style: .medium)
@IBAction func buttonTapped(_ sender: UIButton) {
impactFeedbackGenerator.impactOccurred()
}
}
Note: Ensure that the device supports haptic feedback before triggering it.
2. Using UISelectionFeedbackGenerator
The UISelectionFeedbackGenerator is used to provide haptic feedback when a selection changes, such as when a user taps a button or selects an item in a list.
| Property | Description | Usage |
|---|---|---|
| selectionChanged() | Triggers haptic feedback when a selection changes | |
Note: This feedback is typically used for selection changes in lists or when a user interacts with controls that have a visual state change.
3. Using UINotificationFeedbackGenerator
| Property | Value | Description |
|---|---|---|
| notificationType | .success, .warning, .error |
Defines the type of haptic feedback to be generated |
Example: Triggering Notification Feedback
import UIKit
class ViewController: UIViewController {
let feedbackGenerator = UINotificationFeedbackGenerator()
@IBAction func triggerFeedback(_ sender: UIButton) {
feedbackGenerator.notificationOccurred(.success)
}
}
Note:
UINotificationFeedbackGenerator is designed for feedback related to user actions, such as successful completion or errors.4. Preparing Haptic Generators
| Property | Value | Description |
|---|---|---|
| HapticGenerator | UIImpactFeedbackGenerator |
Generates impact feedback with varying intensity |
| HapticGenerator | UISelectionFeedbackGenerator |
Generates selection feedback for UI element changes |
| HapticGenerator | UIImpactFeedbackGenerator |
Generates impact feedback with varying intensity |
Example: Initializing a Haptic Generator
import UIKit
let impactGenerator = UIImpactFeedbackGenerator(style: .medium)
impactGenerator.prepare()
Note: Call
prepare() before triggering haptics to reduce latency.5. Choosing Feedback Intensity
| Intensity Level | Description | Usage | Code Example |
|---|---|---|---|
| light | Subtle haptic feedback | For minor interactions or confirmations | |
| medium | Standard haptic feedback | For most standard interactions | |
| heavy | Strong haptic feedback | For significant actions or errors | |
6. Using Core Haptics
| Property | Value | Description |
|---|---|---|
| HapticEngine | CHHapticEngine |
Main class for managing haptic feedback in iOS |
| HapticPattern | CHHapticPattern |
Represents a sequence of haptic events |
| HapticEvent | CHHapticEvent |
Represents a single haptic event with timing and parameters |
Example: Initializing Core Haptics Engine
import CoreHaptics
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else {
print("Haptics not supported")
return
}
let engine = try CHHapticEngine()
try engine.start()
Example: Playing a Simple Haptic
let event = CHHapticEvent(
eventType: .hapticTransient,
parameters: [
CHHapticEventParameter(parameterID: .hapticIntensity, value: 0.8),
CHHapticEventParameter(parameterID: .hapticSharpness, value: 0.5)
],
relativeTime: 0
)
let pattern = try CHHapticPattern(events: [event], parameters: [])
try engine.play(pattern)
Example: Creating a Custom Haptic Pattern
let events: [CHHapticEvent] = [
CHHapticEvent(
eventType: .hapticTransient,
parameters: [CHHapticEventParameter(parameterID: .hapticIntensity, value: 0.7)],
relativeTime: 0
),
CHHapticEvent(
eventType: .hapticContinuous,
parameters: [CHHapticEventParameter(parameterID: .hapticIntensity, value: 0.9)],
relativeTime: 0.1,
duration: 0.3
)
]
let pattern = try CHHapticPattern(events: events, parameters: [])
try engine.play(pattern)
Note: Core Haptics requires iOS 13.0 or later and is only available on devices with haptic feedback capabilities.
7. Creating Custom Haptic Patterns
| Property | Value | Description |
|---|---|---|
| HapticFeedbackGenerator | UIImpactFeedbackGenerator |
Generates impact feedback with different intensity levels |
| HapticFeedbackGenerator | UISelectionFeedbackGenerator |
Generates selection feedback for UI element interactions |
| HapticFeedbackGenerator | UIImpactFeedbackGenerator |
Generates notification feedback for system events |
Example: Creating a Custom Haptic Pattern
import UIKit
class HapticPatternManager {
let generator = UIImpactFeedbackGenerator(style: .medium)
func createCustomHapticPattern() {
generator.impactOccurred()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.generator.impactOccurred()
}
}
}
Note: Custom haptic patterns are best used for user interactions that require tactile feedback to confirm actions or provide a sense of weight and response.
8. Synchronizing Haptics with Audio
| Property | Description | Notes |
|---|---|---|
| HapticFeedbackGenerator | Generates haptic feedback using system-provided patterns | Available in iOS 10+ |
| AudioEngine | Manages audio processing and playback | Part of AVAudioEngine framework |
| AVAudioPlayer | Plays audio files with precise timing control | Supports synchronization with haptics |
Example: Synchronizing Haptic and Audio Playback
import AVFoundation
import UIKit
class HapticAudioSync {
let audioEngine = AVAudioEngine()
let playerNode = AVAudioPlayerNode()
let hapticGenerator = UIImpactFeedbackGenerator(style: .medium)
func setupAudioAndHaptics() {
// Setup audio engine
audioEngine.attach(playerNode)
audioEngine.connect(playerNode, to: audioEngine.mainMixerNode, format: nil)
// Load and play audio file
guard let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") else { return }
do {
let audioFile = try AVAudioFile(forReading: url)
playerNode.scheduleFile(audioFile, at: nil, options: .loops)
} catch {
print("Error loading audio file: \(error)")
}
// Start engine
do {
try audioEngine.start()
} catch {
print("Error starting audio engine: \(error)")
}
// Play haptic feedback at same time as audio
hapticGenerator.impactOccurred()
}
}
Note: For best synchronization, ensure that the haptic generator is triggered just before or at the same time as audio playback begins.
Best Practices for Synchronizing Haptics with Audio
- Use
UIImpactFeedbackGeneratorfor tactile feedback that aligns with audio events. - Ensure timing precision by triggering haptics in sync with audio playback start.
- Test on physical devices to verify timing accuracy and responsiveness.
9. Testing Haptic Feedback
Example: Triggering Haptic Feedback
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
@IBAction func buttonTapped(_ sender: UIButton) {
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
}
}
| Feedback Type | Description | Usage |
|---|---|---|
| UIImpactFeedbackGenerator.Style.light | Light impact feedback | For light touches or subtle interactions |
| UIImpactFeedbackGenerator.Style.medium | Medium impact feedback | For standard interactions like button taps |
| UIImpactFeedbackGenerator.Style.heavy | Heavy impact feedback | For significant actions or errors |
| UIImpactFeedbackGenerator.Style.rigid | Rigid impact feedback | For solid, precise impacts |
| UIImpactFeedbackGenerator.Style.soft | Soft impact feedback | For gentle, soft interactions |
Note: Haptic feedback is only available on devices that support it. Always check for availability before using.
Warning: Avoid overusing haptic feedback to prevent user fatigue and maintain a clean UX.
Testing Guidelines
- Test on physical devices with haptic support
- Ensure feedback matches user actions
- Use appropriate intensity levels for context
- Consider accessibility needs (e.g., users with hearing impairments)
10. Understanding Haptic Guidelines
| Guideline | Description | Usage |
|---|---|---|
| Intensity | Feedback intensity levels (Light, Medium, Heavy) | Use appropriate intensity based on user context |
| Type | Impact, Tick, Soft, etc. | Select type matching user action or system state |
| Timing | Duration and timing of feedback | Keep feedback brief (under 100ms) |
| Context | Appropriate use cases for haptics | Use for confirmations, errors, and interactions |
Note: Haptic feedback should enhance user experience without being distracting or excessive.