SwiftUIHaptics 库

GitHub

一个开源库,提供一个通用服务,用于需要触觉反馈的项目。

作为 XII's 的 iOS、macOS 和 watchOS 应用程序中各种项目的可重用组件而开发。

安装

Swift Package Manager

  1. 在 Xcode 中,选择 File > Swift Packages > Add Package Dependency。
  2. 使用此存储库的 URL 按照提示操作
  3. 选择 SwiftUIHaptics 库添加到您的项目

依赖项

许可证

请参阅 LICENSE 文件。

支持的平台

此库与 iOS、watchOS 和 macOS 平台兼容。在 iOS/watchOS 上,触觉引擎用于播放各种触觉事件。但是,在 macOS 上,所有事件都会被简单地跳过。提供 MacOS 支持仅仅是为了允许同一段 SwiftUI 代码与触觉服务交互,而无需使用操作系统检查来“门控”其逻辑。

定义触觉事件 (Source)

struct HapticEvent {
  let underlyingEvents: [CHHapticEvent]
}

一个包含一系列 CHHapticEvent 的结构体,通过 HapticsService 播放。

创建触觉事件 (Source)

单个事件

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 实例的所有底层事件来创建触觉事件的模式。

从现有 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
          )
    }
  )
}

连接 HapticsService

import SwiftUI
import SwiftUIHaptics

@main
struct FooApplication : App {
  @StateObject private var hapticsService = HapticsService()
  
  var body: some Scene {
    WindowGroup {
      ContentView()
        .environmentObject(hapticsService)
    }
  }
}

在您的 View 中触发事件

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