Skip to content

TipKit Basics (SwiftUI)

A SwiftUI guide for coding agents. Also covers tipkit popover tip, feature discovery hints ios, tipview inline, tips configure frequency, onboarding tooltips.

TipKit shows feature-discovery hints anchored to your UI. A tip is a type conforming to the Tip protocol; show it with popoverTip or an inline TipView, and nothing appears until you call Tips.configure() at app start.

Defining and Showing a Tip

Only title is required. An enum works well for a family of tips.

enum FeedTip: Tip {
  case add

  var title: Text {
    switch self {
    case .add: Text("Add more items.")
    }
  }
}
Button("Add", systemImage: "plus", action: feed.addItem)
  .popoverTip(FeedTip.add)
@main
struct MyApp: App {
  init() {
    try? Tips.configure()
  }
  var body: some Scene {
    WindowGroup { ContentView() }
  }
}

Forgetting Tips.configure() is the classic gotcha: the code compiles and no tip ever shows. TipView(FeedTip.add, arrowEdge: .trailing) renders the same tip inline, in a list row for example.

Message, Image, and Actions

Optional message, image, and actions properties enrich the tip. The action handler comes from the popoverTip or TipView call site and matches on the action id.

var actions: [Action] {
  [Action(id: "add", title: "Add")]
}
Button("Add", systemImage: "plus", action: feed.addItem)
  .popoverTip(FeedTip.add) { action in
    if action.id == "add" {
      feed.addItem()
    }
  }

Configuration

Tips.configure takes options. displayFrequency throttles tips (immediate, weekly, monthly). datastoreLocation moves the tip state, which defaults to user defaults, into an app group container so iPhone and watch stay in sync.

try? Tips.configure([
  .displayFrequency(.immediate),
  .datastoreLocation(.groupContainer(identifier: "com.myapp.group"))
])

UIKit and Debugging

TipKit is not SwiftUI-only: TipUIView, TipUIPopoverViewController, and TipUICollectionViewCell cover UIKit. For testing, Tips.resetDatastore() clears state, and Tips.showAllTipsForTesting() or Tips.hideAllTipsForTesting() force tips on or off.

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-basics" })
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