-
Notifications
You must be signed in to change notification settings - Fork 677
Expand file tree
/
Copy pathHaptics.swift
More file actions
110 lines (93 loc) · 3.44 KB
/
Haptics.swift
File metadata and controls
110 lines (93 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import AudioToolbox
import UIKit
import CoreHaptics
@objc public class Haptics: NSObject {
var selectionFeedbackGenerator: UISelectionFeedbackGenerator?
private var hapticEngine: CHHapticEngine?
private var idleTimer: Timer?
private let idleInterval: TimeInterval = 5.0
private func initializeEngine() {
do {
let engine = try CHHapticEngine()
engine.resetHandler = { [weak self] in
do {
try self?.hapticEngine?.start()
} catch {
self?.hapticEngine = nil
}
}
engine.stoppedHandler = { [weak self] _ in
self?.hapticEngine = nil
}
try engine.start()
hapticEngine = engine
} catch {
hapticEngine = nil
}
}
private func resetIdleTimer(after duration: TimeInterval) {
idleTimer?.invalidate()
idleTimer = Timer.scheduledTimer(
withTimeInterval: duration + idleInterval, repeats: false
) { [weak self] _ in
self?.shutdownEngine()
}
}
private func shutdownEngine() {
idleTimer?.invalidate()
idleTimer = nil
hapticEngine?.stop(completionHandler: nil)
hapticEngine = nil
}
@objc public func impact(_ impactStyle: UIImpactFeedbackGenerator.FeedbackStyle) {
let generator = UIImpactFeedbackGenerator(style: impactStyle)
generator.impactOccurred()
}
@objc public func notification(_ notificationType: UINotificationFeedbackGenerator.FeedbackType) {
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(notificationType)
}
@objc public func selectionStart() {
self.selectionFeedbackGenerator = UISelectionFeedbackGenerator()
self.selectionFeedbackGenerator?.prepare()
}
@objc public func selectionChanged() {
if let generator = self.selectionFeedbackGenerator {
generator.selectionChanged()
generator.prepare()
}
}
@objc public func selectionEnd() {
self.selectionFeedbackGenerator = nil
}
@objc public func vibrate() {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
@objc public func vibrate(_ duration: Double) {
if CHHapticEngine.capabilitiesForHardware().supportsHaptics {
if hapticEngine == nil {
initializeEngine()
}
resetIdleTimer(after: duration)
guard let engine = hapticEngine else {
vibrate()
return
}
do {
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
let continuousEvent = CHHapticEvent(eventType: .hapticContinuous,
parameters: [intensity, sharpness],
relativeTime: 0.0,
duration: duration)
let pattern = try CHHapticPattern(events: [continuousEvent], parameters: [])
let player = try engine.makePlayer(with: pattern)
try player.start(atTime: 0)
} catch {
vibrate()
}
} else {
vibrate()
}
}
}