## SwiftUI .sensoryFeedback cheat sheet

- Use case: Every built-in SwiftUI feedback value (iOS 17+) in one view, wired to trigger values.
- Feel: Covers the full built-in vocabulary: outcomes, ticks, impacts, and state changes.
- APIs: .sensoryFeedback(_:trigger:), SensoryFeedback
- Minimum OS: iOS 17+

### SwiftUI (iOS 17+)

```swift
import SwiftUI

struct SensoryFeedbackCheatSheet: View {
    @State private var trigger = 0

    var body: some View {
        Button("Fire haptic") { trigger += 1 }

            // --- Outcomes -------------------------------------------------
            .sensoryFeedback(.success, trigger: trigger)  // task finished
            // .sensoryFeedback(.warning, trigger: trigger)
            // .sensoryFeedback(.error,   trigger: trigger)

            // --- Ticks & value changes ------------------------------------
            // .sensoryFeedback(.selection, trigger: trigger)   // picker tick
            // .sensoryFeedback(.increase,  trigger: trigger)   // stepper +
            // .sensoryFeedback(.decrease,  trigger: trigger)   // stepper −

            // --- Physical impacts -----------------------------------------
            // .sensoryFeedback(.impact, trigger: trigger)      // default collision
            // .sensoryFeedback(.impact(weight: .light,  intensity: 0.7), trigger: trigger)
            // .sensoryFeedback(.impact(weight: .medium, intensity: 1.0), trigger: trigger)
            // .sensoryFeedback(.impact(weight: .heavy,  intensity: 1.0), trigger: trigger)
            // .sensoryFeedback(.impact(flexibility: .soft,  intensity: 0.8), trigger: trigger)
            // .sensoryFeedback(.impact(flexibility: .solid, intensity: 0.8), trigger: trigger)
            // .sensoryFeedback(.impact(flexibility: .rigid, intensity: 0.8), trigger: trigger)

            // --- Activities & alignment -----------------------------------
            // .sensoryFeedback(.start, trigger: isRecording)   // activity began
            // .sensoryFeedback(.stop,  trigger: isRecording)   // activity ended
            // .sensoryFeedback(.alignment,   trigger: snapped) // canvas guide snap
            // .sensoryFeedback(.levelChange, trigger: zoomLevel)
            // .sensoryFeedback(.pathComplete, trigger: done)   // iOS 18+
    }
}

// Conditional variant — decide at fire time:
struct ConditionalFeedback: View {
    @State private var result: Result<Void, Error>? = nil
    @State private var attempt = 0

    var body: some View {
        Button("Submit") { attempt += 1 /* ... */ }
            .sensoryFeedback(trigger: attempt) { _, _ in
                switch result {
                case .success: return .success
                case .failure: return .error
                case .none:    return nil // returning nil plays nothing
                }
            }
    }
}
```

### Notes
- The feedback fires whenever the trigger value changes — use a counter for "fire every tap" or a Bool/state for transitions.
- Use the closure form to inspect old/new values and pick a feedback (or nil) at runtime.
- .selection only fires while a value is actively changing; it is the SwiftUI face of UISelectionFeedbackGenerator.
