Skip to content

Trigger Value Pattern (SwiftUI)

A SwiftUI guide for coding agents. Also covers trigger parameter modifier, run action on value change, onchange side effect, scrollindicatorsflash, declarative imperative bridge, custom trigger view modifier.

A trigger value is an equatable value a modifier observes; when the value changes, the modifier runs its action. It is SwiftUI's declarative way to fire an imperative side effect, used by sensoryFeedback, scrollIndicatorsFlash, and mapCameraKeyframeAnimator.

The Pattern in the Framework

The action never runs on appearance, only on change. Toggling a boolean is a common way to fire it on demand.

List(messages, id: \.self) { message in
  Text(verbatim: message)
}
.sensoryFeedback(.impact, trigger: messages)
.scrollIndicatorsFlash(trigger: messages)

Building Your Own

A custom trigger modifier is a ViewModifier with a generic Trigger: Equatable property and an onChange in its body. Wrap it in a View extension for call-site ergonomics.

struct PlaySoundViewModifier<Trigger: Equatable>: ViewModifier {
  let sound: URL
  let trigger: Trigger

  func body(content: Content) -> some View {
    content
      .onChange(of: trigger) {
        if let player = try? AVAudioPlayer(contentsOf: sound) {
          player.play()
        }
      }
  }
}

extension View {
  func playSound(_ sound: URL, trigger: some Equatable) -> some View {
    self.modifier(PlaySoundViewModifier(sound: sound, trigger: trigger))
  }
}
List(messages, id: \.self) { message in
  Text(verbatim: message)
}
.playSound(
  Bundle.main.url(forResource: "sound", withExtension: "wav")!,
  trigger: messages
)

Triggering Cancellation

The same shape carries commands into a component. An AsyncButton can take a cancellation trigger and cancel its stored task when the value changes.

.disabled(isRunning)
.onChange(of: cancellation) {
  task?.cancel()
}

The caller just toggles a boolean state to cancel. Any equatable type works as the trigger; the value itself carries no meaning, only its change does.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-trigger-value-pattern" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems