前言

SwiftUI 引入了新的 sensoryFeedback 视图修饰符,使咱们能够在一切 Apple 渠道上播映触觉反应。下面咱们将学习如何运用 sensoryFeedback 修饰符在应用程序中的不同操作中供给触觉反应。

布景介绍

iOS 17 之前,假如你想要从 SwiftUI 视图中向用户供给触觉反应,你会运用其中一个 UIKit(或 AppKit)的反应生成器。例如,运用挑选反应生成器:

struct ListView: View {
  @Binding var store: Store
  let generator = UISelectionFeedbackGenerator()
  var body: some View {
    List(store.items, selection: $store.selection) { ... }
    .onChange(of: store.selection) { oldValue, newValue in
      if newValue != nil {
        generator.selectionChanged()
      }
    }
  }
}

在 iOS 17 中,Apple 直接向 SwiftUI 中添加了一系列感觉反应的视图修饰符,以播映触觉和/或音频反应。

渠道支撑

并非一切渠道都支撑一切反应选项。以下是我所知道的每个渠道上可用的内容列表。请注意,iPad不支撑触觉反应。

仅支撑watchOS

  • start:活动开端
  • stop:活动停止

支撑watchOS和iOS

  • decrease:重要值减少到明显阈值以下
  • increase:重要值增加到明显阈值以上
  • selection:UI元素的值正在更改
  • success:使命成功完结
  • warning:使命发生警告
  • error:使命发生过错
  • impact:UI元素磕碰时的物理冲击

请注意,impact反应有两个变体,让您指定元素磕碰的分量(轻,中,重)或灵敏性(刚性,柔软,实心)。在这两种情况下,您还能够更改强度(默以为1.0):

// 默许impact反应
.impact()
// 具有柔韧性并增加强度的impact
.impact(flexibility: .rigid, intensity: 2.0)
// 具有分量并增加强度的impact
.impact(weight: .heavy, intensity: 2.0)

基本用法

要在 SwiftUI 视图中播映触觉反应,咱们只需要运用 sensoryFeedback 视图修饰符,带有两个参数。第一个界说了反应款式,第二个是触发器值。

struct ContentView: View {
    @State private var store = Store()
    var body: some View {
        NavigationStack {
            List(store.results, id: .self) { result in
                Text(result)
            }
            .searchable(text: $store.query)
            .sensoryFeedback(.success, trigger: store.results)
        }
    }
}

在上面的示例中,咱们运用 sensoryFeedback 视图修饰符,带有成功款式。咱们还将存储的 results 属性界说为触发器。这意味着 SwiftUI 将在存储的成果更改时播映成功款式的触觉反应。

预界说款式

SwiftUI 供给了许多预界说的反应款式,如 successwarningerrorselectionincreasedecreasestartstopalignmentlevelChangeimpact 等。

struct ContentView: View {
    @State private var trigger = false
    var body: some View {
        NavigationStack {
            Button("Action") {
                // 进行某些操作
                trigger.toggle()
            }
            .sensoryFeedback(
                .impact(weight: .heavy, intensity: 0.9),
                trigger: trigger
            )
        }
    }
}

如上所示,impact 款式答应咱们调整反应的权重和强度。请记住,最好运用预界说的款式,并在超级自界说的情况下自界说触觉反应。

依据触发器值挑选款式

sensoryFeedback 视图修饰符的另一种变体答应咱们依据触发器值挑选特定的反应款式。在这里,咱们在存储包含成果时播映成功反应,并在成果为空时播映过错反应。

struct ContentView: View {
    @State private var store = Store()
    var body: some View {
        NavigationStack {
            List(store.results, id: .self) { result in
                Text(result)
            }
            .searchable(text: $store.query)
            .sensoryFeedback(trigger: store.results) { oldValue, newValue in
                return newValue.isEmpty ? .error : .success
            }
        }
    }
}

SwiftUI 还供给了在触发器值上界说条件的选项,决定是否播映预界说的反应款式。

运用场景

这些感觉反应修饰符都是根据触发器的。触发器需要是可同等的类型。有三种感觉反应视图修饰符的变体:

当值更改时触发

struct ListView: View {
  @Binding var store: Store
  var body: some View {
    List(store.items, selection: $store.selection) { ... }
    .sensoryFeedback(.selection, trigger: store.selection)
  }
}

视图修饰符的第一个参数是 SensoryFeedback 类型。并非一切反应类型都适用于一切渠道。当触发器值更改时,反应会播映。

运用条件闭包触发

假如要更灵敏地控制何时触发反应,请运用带有条件闭包版别的视图修饰符。例如,仅在挑选更改为非空值时播映挑选反应:

.sensoryFeedback(.selection, trigger: store.selection) {
  oldValue, newValue in
    newValue != nil
}

条件闭包接收监视的触发器值的旧值和新值。在闭包中,回来一个布尔值,指示是否应播映反应。

运用反应闭包触发

要控制播映何种反应,请运用视图修饰符的反应闭包版别。例如,根据过错代码供给警告或过错反应:

// @State private var errorCode: Int = 0
.sensoryFeedback(trigger: errorCode) { oldValue, newValue in
    switch newValue {
    case 1: .warning
    case 2: .error
    default: nil
    }
}

在这种情况下,在闭包中回来所需的反应,假如不想要任何反应,则回来nil。

能够运转 Demo

供给一个能够运转的 Demo,完好代码如下:

import SwiftUI
struct ContentView: View {
    @State private var store = Store()
    var body: some View {
        NavigationView {
            List(store.results, id: .self) { result in
                Text(result)
            }
            .searchable(text: $store.query)
            .sensoryFeedback(.success, trigger: store.results)
            .navigationTitle("Sensory Feedback Demo")
        }
    }
}
struct Store {
    @State var query: String = ""
    @State var results: [String] = ["Result 1", "Result 2", "Result 3"]
}

Demo 包含一个带有触觉反应的 SwiftUI 列表。你能够依据需要进行进一步的调整和扩展。

总结

SwiftUI引入了新的sensoryFeedback视图修饰符,为一切Apple渠道供给触觉反应。通过简略的附加,咱们能够界说反应款式和触发器值,实现了在应用程序中不同操作发生的触觉作用。支撑多种预界说款式,如success、warning、error,以及个性化的impact款式。对于触发器值的处理也十分灵敏,能够依据其条件挑选不同的反应款式。

整体而言,这个新的视图修饰符为提高应用的可访问性和用户体验供给了简洁的方式。在运用时需谨慎,防止过多搅扰用户。期望通过学习这个新特性,开发者能更好地运用触觉反应功能,提升应用的交互性。