主要内容翻译自:SwiftUI Sensory Feedback
在 iOS 17 中,SwiftUI 增加了一个地道的 modifier 来供给轰动反应。
SwiftUI 经典状况再现。好消息:咱们新增了一个 modifier 实现了 UIKit 的一个功能,更加优雅。坏消息:从最新的版别的 iOS 开始支持。
在 iOS 17 之前的状况
在 iOS 17 之前,轰动反应经过 UIFeedbackGenerator
的子类实现(UIImpactFeedbackGenerator、UISelectionFeedbackGenerator. UINotificationFeedbackGenerator
)。
运用的方法大概这样:
struct OldFeedback: View {
@State var value: Bool = true
let generator = UISelectionFeedbackGenerator()
var body: some View {
Toggle("Switch", isOn: $value)
.onChange(of: value, {
generator.selectionChanged()
})
}
}
iOS 17:Sensory Feedback
在 iOS 17 中引入了原生的 sensoryFeedback
modifier:
struct Feedback: View {
@State var value: Bool = true
var body: some View {
Toggle("Switch", isOn: $value)
.sensoryFeedback(.selection, trigger: value)
}
}
这个方法还很贴心的添加了尾随的判断闭包,相似 filter。因为咱们或许不是每次值的改换都轰动,能够把筛选条件加到闭包里:
struct Feedback: View {
@State var value: Bool = true
var body: some View {
Toggle("Switch", isOn: $value)
.sensoryFeedback(.selection, trigger: value,
condition: { oldValue, newValue in
if newValue == true {
return true
} else {
return false
}
})
}
}
还有一个签名是能够经过调查的值来回来不同的轰动:
struct Feedback: View {
@State var value: Bool = true
var body: some View {
Toggle("Switch", isOn: $value)
.sensoryFeedback(trigger: value) { oldValue, newValue in
if newValue == true {
return SensoryFeedback.selection
} else {
return SensoryFeedback.warning
}
}
}
}
不同的渠道的差异
SwiftUI 天生就支持苹果全渠道。轰动反应又具有渠道特性(比方在 mac 上便是触摸板的轰动,在手表上是 taptic engine),因而轰动选项 SensoryFeedback
的值也是区别渠道的。小常识:iPad 上没有轰动。
watchOS only
- start: Activity started
- stop: Activity stopped
start 和 stop 通常用来表明一个活动的开始和结束(比方手表上的计时)。
macOS only
- alignment: a dragged item is in alignment with another item.
- levelChange: indicates movement between discrete levels of pressure. For example, holding a fast-forward button.
这两个轰动都是针对 mac 的触摸板的。alignment 场景是当你拖动一个元素时,要提醒对齐状态时给与的小轰动。levelChange 场景是按压的力度,比方长按一个元素能够敞开排序,能够给出一个相似于重按的反应。
watchOS & iOS
剩余的选项都是 watchOS 和 iOS 通用的。
轰动选项有这些:
- decrease: Important value decreased below a significant threshold
- increase: Important value increased above a significant threshold
特别要提一下的是 decrease、increase。这两种轰动文档上写的是 watchOS only,但是现在在 iOS 也能够正常轰动。
- selection: A UI element’s values are changing.
- success: A task completed successfully
- warning: A task produced a warning
- error: A task produced an error
- impact: A physical impact when UI elements collide.
自界说轰动参数
在 impact
这个选项中,还额外给了两个参数来调理轰动:
- weight:调理轰动的强度,有light、medium、heavy三档。你乃至能够在这个基础上再设置强度,他真的我哭死。
- flexibility:震感曲线,能够理解为绷簧的软硬,轰动是洪亮仍是柔软一点,有rigid、solid、soft三档。你乃至能够在这个基础上再设置强度,他真的我哭死。
代码演示:
struct Feedback: View {
@State var value: Bool = true
var body: some View {
Toggle("Switch", isOn: $value)
.sensoryFeedback(trigger: value) { oldValue, newValue in
if newValue == true {
return SensoryFeedback.impact(weight: .light, intensity: 1.5)
} else {
return SensoryFeedback.impact(flexibility: .rigid, intensity: 2.0)
}
}
}
}
HIG 运用主张
苹果在 HIG 中对怎么(Human Interface Guidelines – Playing haptics)运用轰动有说到一些主张:
- 轰动的类型和体系界说一致。比方体系供给了选中的轰动,用户在体系其他地方也很熟悉选中的轰动,这个时分 app 里就主张运用和体系行为一致的轰动方法。
- 不用过度运用。
- 能够允许用户封闭轰动。
- 整个 app 中的轰动逻辑要保持一致。