译自 www.hackingwithswift.com/books/ios-s…
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀
用 UINotificationFeedbackGenerator 和 Core Haptics 来产生振动
尽管 SwiftUI 并不内建震动反馈的功能,我们可以借助 UIKit 和 Core Haptics 轻松地实现震动功能。这两个框架都是内建于系统的,对于所有 iPhone 平台都是可用的。以防你不了解震动反馈这个术语,我简单解释一下,“震动反馈” 在设备中内置了一个小的马达,用于提供点击和振铃的感知。
UIKit 有一个非常简单的震动反馈实现,这并不意味着你就可以忽略它。这个功能本来就可以用最简单的方式使用,比如只需要反馈内置的 “成功” 或者 “失败”。这意味着,用户可以通过学习,掌握某件事情的感知是什么样的。比如,你使用了成功的震动,那么某些用户 —— 尤其是那些重度依赖震动反馈的用户,比如盲人,可以不借助应用的其他输出信息就知道某个操作的结果。
为了尝试 UIKit 的震动反馈,添加下面这个方法到 ContentView:
func simpleSuccess() {
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
}
你可以在某个手势,比如 onTapGesture() 中触发这个反馈:
Text("Hello, World!")
.onTapGesture(perform: simpleSuccess)
试着把 .success 替换成 .error 后者 .warning,看看其间的差别 —— 我认为 .success 和 .warning 相似但是不同。
对于更高级的震动反馈,Apple 提供了一个叫 Core Haptics 的框架。看起来 Apple 的团队为其倾注了不少心血,我认为这个框架是隐藏在 iOS 背后的明珠 —— 我在它刚刚发布的时候就被深深地吸引了!
Core Haptics 能让我们通过组合点击,跟进的振铃,参数曲线等来定制大量的自定义震动反馈。我不会逐一深入,因为这样就脱离主题了,不过我会给一个例子,让你自行尝试。
首先,导入这个框架:
import CoreHaptics
然后,创建一个 CHHapticEngine 实例作为属性 —— 它是实际负责创建震动的对象。
@State private var engine: CHHapticEngine?
在我们的主视图出现时,我们就需要准备好震动。我们可以通过添加 handler 来帮助应用的活动回归活跃,比如当应用进入后台的时候。简单起见,如果设备支持震动反馈,我们才执行反馈,并且在出错时打印错误信息。
把下面这个方法添加到 ContentView:
func prepareHaptics() {
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else { return }
do {
self.engine = try CHHapticEngine()
try engine?.start()
} catch {
print("创建引擎时出现错误: \(error.localizedDescription)")
}
}
再接下来是有趣的部分:我们可以通过配置参数来控制震动的强度(.hapticIntensity) 以及“锐度” (.hapticSharpness),然后放入一个震动事件,并且设置相对时间偏移。“锐度”听起来是一个很奇怪的术语,不过只要你尝试之后,就会发现这个词说得通了。0 的锐度和 1 的锐度感觉是完全不同的。至于相对时间偏移,能让我们在单个序列里创建许多震动。
把下面这个方法添加到 ContentView:
func complexSuccess() {
// 确保设备支持震动反馈
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else { return }
var events = [CHHapticEvent]()
// 创建一个强烈的,锐利的震动
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1)
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1)
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 0)
events.append(event)
// 将震动事件转换成模式,立即播放
do {
let pattern = try CHHapticPattern(events: events, parameters: [])
let player = try engine?.makePlayer(with: pattern)
try player?.start(atTime: 0)
} catch {
print("Failed to play pattern: \(error.localizedDescription).")
}
}
为了尝试我们的自定义震动,把 ContentView 的 body 属性修改成下面这样:
Text("Hello, World!")
.onAppear(perform: prepareHaptics)
.onTapGesture(perform: complexSuccess)
你可以修改强度,锐度和事件,尝试不同参数下的震动效果。代码如下:
for i in stride(from: 0, to: 1, by: 0.1) {
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(i))
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: Float(i))
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: i)
events.append(event)
}
for i in stride(from: 0, to: 1, by: 0.1) {
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(1 - i))
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: Float(1 - i))
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 1 + i)
events.append(event)
}
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~