一个开源库,提供一个通用服务,用于需要触觉反馈的项目。
作为 XII's 的 iOS、macOS 和 watchOS 应用程序中各种项目的可重用组件而开发。
SwiftUIHaptics
库添加到您的项目请参阅 LICENSE 文件。
此库与 iOS、watchOS 和 macOS 平台兼容。在 iOS/watchOS 上,触觉引擎用于播放各种触觉事件。但是,在 macOS 上,所有事件都会被简单地跳过。提供 MacOS 支持仅仅是为了允许同一段 SwiftUI 代码与触觉服务交互,而无需使用操作系统检查来“门控”其逻辑。
struct HapticEvent {
let underlyingEvents: [CHHapticEvent]
}
一个包含一系列 CHHapticEvent
的结构体,通过 HapticsService
播放。
extension HapticEvent {
static func single(
intensity: Float? = nil,
sharpness: Float? = nil,
attack: Float? = nil,
decay: Float? = nil,
release: Float? = nil,
sustained: Float? = nil,
relativeTime: TimeInterval = 0.0,
duration: TimeInterval = 0.0
) -> HapticEvent
}
创建一个单独的 HapticEvent
,可以指定所有参数并默认其他参数。
extension HapticEvent {
static func pattern(events: [HapticEvent]) -> HapticEvent
static func pattern(_ events: HapticEvent...) -> HapticEvent
}
通过组合提供的 HapticEvent
实例的所有底层事件来创建触觉事件的模式。
extension HapticEvent {
func timeShifted(
relativeTime: TimeInterval,
duration: TimeInterval
) -> HapticEvent
}
返回一个时间偏移的 HapticEvent
,并指定提供的相对时间和播放持续时间。
HapticsService
(Source)class HapticsService : ObservableObject {
var isAvailable: Bool { get }
init()
func play(event: HapticEvent) {
}
extension HapticEvent {
static let strong: HapticEvent =
.single(intensity: 0.75, sharpness: 0.75, decay: -0.5)
static let normal: HapticEvent =
.single(intensity: 0.5, sharpness: 0.5, decay: -0.5)
static let ripPattern: HapticEvent = .pattern(
events: (0..<12).map { index in
HapticEvent.normal
.timeShifted(
relativeTime: Double(index) * 0.025,
duration: 0.1
)
}
)
}
import SwiftUI
import SwiftUIHaptics
@main
struct FooApplication : App {
@StateObject private var hapticsService = HapticsService()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(hapticsService)
}
}
}
struct ContentView : View {
@EnvironmentObject private var hapticsService: HapticsService
var body: some View {
VStack {
Spacer()
Button("Normal") {
hapticsService.play(event: .normal)
}
.buttonStyle(BorderedButtonStyle())
.padding(20)
Button("Strong") {
hapticsService.play(event: .strong)
}
.buttonStyle(BorderedButtonStyle())
.padding(20)
Button("Rip!!!") {
hapticsService.play(event: .ripPattern)
}
.buttonStyle(BorderedButtonStyle())
.padding(20)
Spacer()
}
}
}
服务的模拟在预览和其他应用程序中可能很有用。 HapticsService
附带模拟支持,可以在调试版本中按如下方式使用
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
PreviewView()
}
}
struct PreviewView : View {
@StateObject private var mockHapticsService = MockHapticsService()
@State private var eventsPlayed: Int = 0
var body: some View {
VStack {
Text("# of events played: \(eventsPlayed)")
ContentView()
.environmentObject(mockHapticsService as HapticsService)
}
.onAppear {
mockHapticsService.playCallback = { _ in
eventsPlayed += 1
}
}
}
}
#endif