CoreHaptics 是 iOS13 中的新API,同时只有 iPhone 8 及之后的机型支持。CoreHaptics 提供了更加细腻,可控的震动表达方式,可以令APP产生一种全新的体验。
使用 CoreHaptics 播放震动需要一下几步:
1、检测 CoreHaptics 是否可用
if !CHHapticEngine.capabilitiesForHardware().supportsHaptics {
return
}
2、初始化震动引擎
do {
// 播放之前需要初始化好震动引擎
engine = try CHHapticEngine()
try engine.start()
} catch let e {
print(e)
}
2、播放震动内容
do {
let parameters = [CHHapticEventParameter(parameterID: .hapticIntensity, value: 0.8),
CHHapticEventParameter(parameterID: .hapticSharpness, value: 0.4)]
let events = [CHHapticEvent(eventType: .hapticContinuous,
parameters:parameters,
relativeTime: 0,duration: 2)]
let pattern = try CHHapticPattern(events: events, parameterCurves: [])
let player = try engine.makePlayer(with: pattern)
try player.start(atTime: CHHapticTimeImmediate)
} catch let e {
print(e)
}
震动描述
震动主要分成两类:
Transient:简短的震动,像敲击之类的震动。
Continuous:持续震动,像弦乐器发出的震动
震动组成的两个重要元素是 Intensity 和 Sharpness,翻译过来就是强度和清晰度。Intensity 越大震动越强,Sharpness 越震动越尖锐。
如上面的实例代码,使用 CHHapticEvent 来描述震动的特征。除了 CHHapticEvent 之后,还可以使用字典的形式来描述。想比较来说使用 CHHapticEvent 更方便一些。
let hapticDict = [
CHHapticPattern.Key.pattern: [
[CHHapticPattern.Key.event: [
CHHapticPattern.Key.eventType: CHHapticEvent.EventType.hapticTransient,
CHHapticPattern.Key.time: 0.001,
CHHapticPattern.Key.eventDuration: 1.0]
]
]
]
let pattern = try CHHapticPattern(dictionary: hapticDict)
除此之外,CoreHaptics 可以直接加载 AHAP 文件,AHAP 文件以JSON的形式描述震动。
{
"Pattern":
[
{
"Event":
{
"Time": 0.0,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.4 }
]
}
}
]
}
注意:文件后缀必须是.ahap
if let url = Bundle.main.url(forResource: "test", withExtension: "ahap") {
try engine.playPattern(from: url)
}
震动控制
CoreHaptics 之所以能够表现出多样的效果,主要是能够对震动进行精准的控制。
CHHapticDynamicParameter: 会立即更改属性值;
CHHapticParameterCurve: 会在参数值之间线性插值以确保平滑过渡,可以自定义曲线。
CHHapticDynamicParameter 没有过度,突变的感觉
let pattern = try CHHapticPattern(events: events, parameters: [
CHHapticDynamicParameter(parameterID: .hapticIntensityControl, value: 0.1, relativeTime: 2),
CHHapticDynamicParameter(parameterID: .hapticIntensityControl, value: 1.0, relativeTime: 4),
CHHapticDynamicParameter(parameterID: .hapticIntensityControl, value: 0.1, relativeTime: 6),
CHHapticDynamicParameter(parameterID: .hapticIntensityControl, value: 1.0, relativeTime: 8),
CHHapticDynamicParameter(parameterID: .hapticIntensityControl, value: 0.1, relativeTime: 10),
])
CHHapticParameterCurve 会有过度,渐强渐弱,感觉比较平缓
let pattern = try CHHapticPattern(events: events, parameterCurves: [
CHHapticParameterCurve(parameterID: .hapticIntensityControl, controlPoints: [
CHHapticParameterCurve.ControlPoint(relativeTime: 0, value: 1.0),
CHHapticParameterCurve.ControlPoint(relativeTime: 2, value: 0.1),
CHHapticParameterCurve.ControlPoint(relativeTime: 4, value: 1.0),
CHHapticParameterCurve.ControlPoint(relativeTime: 6, value: 0.1),
CHHapticParameterCurve.ControlPoint(relativeTime: 8, value: 1.0),
CHHapticParameterCurve.ControlPoint(relativeTime: 10, value: 0.1)
], relativeTime: 0)
])
relativeTime 是相对与最近包裹层的时间
其他震动方式
CoreHaptics 是iOS13 才支持的API,对于之前的系统,可使用 UIFeedbackGenerator 或AudioToolbox。
UIFeedbackGenerator
UIFeedbackGenerator是一个抽象类,震动的实现要使用UIImpactFeedbackGenerator、UINotificationFeedbackGenerator与UISelectionFeedbackGenerator。
不同的震动会有不同的感受,震动效果不可编辑,相当于预置的震动效果。
let notificationFeedback = UINotificationFeedbackGenerator()
notificationFeedback.prepare()
notificationFeedback.notificationOccurred(.success)
let impactFeedback = UIImpactFeedbackGenerator(style: .medium)
impactFeedback.prepare()
impactFeedback.impactOccurred()
let selectionFeedback = UISelectionFeedbackGenerator()
selectionFeedback.prepare()
selectionFeedback.selectionChanged()
AudioToolbox
播放简单的持续震动
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);