TechnologiesSwiftUI

SensoryFeedback struct

iOSmacOStvOSwatchOSvisionOSiOS 17.0+✓ renders

Represents a type of haptic and/or audio feedback that can be played.

How it works

SensoryFeedback describes a discrete piece of haptic — and on some platforms audio — feedback that the system plays in response to something happening in your interface, such as a successful submission, a toggle flipping, or a selection landing on a new value. Rather than calling into a haptics engine imperatively, you declare the feedback you want and bind it to a value, letting SwiftUI play it whenever that value changes. Reach for SensoryFeedback when a user action deserves a physical confirmation, so the feel of your app reinforces what the UI is already showing.

  1. Choose a feedback style from the built-in cases

    SensoryFeedback offers named cases that map onto the platform's standard feedback patterns, including semantic outcomes like .success, .warning, and .error, and interaction patterns like .selection, .impact, and .increase/.decrease. Picking the case that matches the meaning of the event lets the system render the correct intensity and texture for each device. The example asks for .success, the celebratory pattern appropriate for a completed action.

  2. Attach it with the sensoryFeedback(_:trigger:) modifier

    You don't play SensoryFeedback directly; you install it on a view with the .sensoryFeedback(_:trigger:) modifier, passing the feedback as the first argument. The modifier lives on whichever view should own the feedback, here the outer VStack, and stays dormant until its trigger fires.

  3. Drive playback by binding to a trigger value

    The trigger parameter takes any Equatable value, and SwiftUI plays the feedback each time that value changes between view updates. In the example the trigger is the count state, so every time the Button runs count += 1, the .success haptic fires exactly once. Because playback is keyed to a value change rather than to the gesture itself, the feedback follows your data instead of your event handling.

  4. Gate or vary feedback with the conditional overloads

    Beyond the simple form, sensoryFeedback provides overloads that take a condition closure to decide whether to play on a given change, and a feedback closure that returns an optional SensoryFeedback so you can select a different pattern — or none — based on the old and new trigger values. These let a single attachment cover cases like playing .success only past a threshold while staying silent otherwise.

Try it — Change .sensoryFeedback(.success, trigger: count) to .sensoryFeedback(.impact, trigger: count) and tap the button to feel the sharper, more neutral tap replace the celebratory success pattern.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

SensoryFeedback.swift
struct SensoryFeedbackDemo: View {
    @State private var count = 0
    var body: some View {
        VStack(spacing: 16) {
            Text("Taps: \(count)")
                .font(.title2)
            Button("Tap me") {
                count += 1
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
        .sensoryFeedback(.success, trigger: count)
    }
}
Live preview
Taps: 0 Tap me
Taps: 0 Tap me
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →