Skip to content

TipKit Rules (SwiftUI)

A SwiftUI guide for coding agents. Also covers tipkit rule macro, tip parameter binding, event donations tipkit, invalidate tip actionperformed, maxdisplaycount option, conditional tips ios.

TipKit decides when a tip appears through four mechanisms: invalidation when the feature gets used, #Rule conditions on parameters, persisted event counts, and options such as a display cap.

Invalidate a Used Tip

When the user performs the action the tip teaches, invalidate it so it never shows again.

Button("Add") {
  FeedTip.add.invalidate(reason: .actionPerformed)
  store.addItem()
}
.popoverTip(FeedTip.add)

Parameters and Rules

@Parameter declares state the rules can read; the #Rule macro gates the tip on it. Sync the parameter from app state, for example in onAppear.

enum FeedTip: Tip {
  @Parameter static var isPro: Bool = false

  case add

  var title: Text { Text("Add") }

  var rules: [Rule] {
    #Rule(Self.$isPro) { isPro in
      isPro == true
    }
  }
}
.popoverTip(FeedTip.add)
.onAppear {
  FeedTip.isPro = isPro
}

The rules property is a RuleBuilder, so several rules combine and all must pass.

Events

An Event is a persisted counter: donations survive app restarts, unlike parameters. Donate on each user action and gate the tip on the count, for example "show after the third add".

static let itemAdded = Event(id: "itemAdded")

var rules: [Rule] {
  #Rule(Self.itemAdded) {
    $0.donations.count >= 3
  }
}
Button("Add") {
  Task {
    await FeedTip.itemAdded.donate()
    store.addItem()
  }
}

Donations also filter by time window: $0.donations.donatedWithin(.week).count == 0.

Options Beat Rules

The options property caps behavior regardless of rules. With MaxDisplayCount(3) the tip never shows a fourth time, even while every rule still passes.

var options: [any TipOption] {
  MaxDisplayCount(3)
}

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-discovering-app-features-with-tipkit-rules" })
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