<!--
{
  "availability" : [
    "iOS: 17.0.0 -",
    "iPadOS: 17.0.0 -",
    "macCatalyst: 17.0.0 -",
    "macOS: 14.0.0 -",
    "tvOS: 17.0.0 -",
    "visionOS: 26.0.0 -",
    "watchOS: 10.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "SwiftUI",
  "identifier" : "/documentation/SwiftUI/View/sensoryFeedback(trigger:_:)",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "SwiftUI"
    ],
    "preciseIdentifier" : "s:7SwiftUI4ViewPAAE15sensoryFeedback7trigger_Qrqd___AA07SensoryE0VSgyctSQRd__lF::OverloadGroup"
  },
  "title" : "sensoryFeedback(trigger:_:)"
}
-->

# sensoryFeedback(trigger:_:)

Plays feedback when returned from the `feedback` closure after the
provided `trigger` value changes.

```
@export(implementation) nonisolated func sensoryFeedback<T>(trigger: T, _ feedback: @escaping () -> SensoryFeedback?) -> some View where T : Equatable
```

## Parameters

`trigger`

A value to monitor for changes to determine when to play.

`feedback`

A closure to determine whether to play the feedback and
what type of feedback to play when `trigger` changes.

## Discussion

For example, you could play different feedback for different state
transitions:

```
struct MyView: View {
    @State private var isExpanded = false

    var body: some View {
        ContentView(isExpanded: $isExpanded)
            .sensoryFeedback(trigger: isExpanded) {
                isExpanded ? .impact : nil
            }
    }
}
```

When the value changes, the new version of the closure will be called,
so any captured values will have their values from the time that the
observed value has its new value.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)