TipKit: showing a popover tip on a SwiftUI toolbar button

Hi folks, there's currently a known issue in TipKit due to which it won't show popover tips on buttons that are inside a SwiftUI ToolbarItem. For example, if you try this code, the popover tip will not appear:

ToolbarItem {
  Button(action: {...}) {
     Label("Tap here", systemImage: "gear")
  }           
  .popoverTip(sampleTip)
}

There's an easy workaround for this issue. Just apply a style to the button. It can be any style. Some examples are bordered, borderless, plain and borderedProminent. Here's a fixed version of the above code:

ToolbarItem {
  Button(action: {...}) {
     Label("Tap here", systemImage: "gear")
  }  
  .buttonStyle(.plain) // Adding this line fixes the issue.
  .popoverTip(sampleTip)
}

Hope this helps anyone running into this issue.

Thanks, but it doesn't seem to be a workaround anymore. :(

import TipKit

struct ContentView: View {
    struct ExampleTip: Tip {
        var title: Text {
            Text("title")
        }

        var message: Text? {
            Text("message")
        }
    }

    var body: some View {
        Text("Hello world")
//            .popoverTip(NewSnippetTip()) //This works
            .toolbar(content: {
                ToolbarItemGroup(placement: ToolbarItemPlacement.bottomBar) {
                    Button(action: {}) {
                        Label("New Snippet", systemImage: "doc.badge.plus")
                    }
                    .buttonStyle(.plain) // WORKAROUND: Adding this line does NOT fix the issue.
                    .popoverTip(ExampleTip())
                }
            })
    }
}

@Iomegano I see the problem. Removing the placement: ToolbarItemPlacement.bottomBar makes it work, but specifying that bottom bar placement prevents the tip from appearing. This may be related to the same underlying issue I mentioned in my original message. We will investigate this issue. Thank you for reporting it.

Just don't use .automatic.

Specifying an arrow direction on my bottomBar toolbar button makes the tooltip show up for me. .popoverTip(tip, arrowEdge: .bottom)

Replacing Label("New", systemImage: "plus.circle.fill") with Image(systemName: "plus.circle.fill") fixed it for me.

For people also struggling with a button styled Toggle(), Apple recommended in a Feedback to also place the .buttonStyle(.borderless) before the .toggleStyle(.button).

Unfortunately that doesn’t work on macOS for me. Neither of the other tricks helped either … but at least for iOS and visionOS it seems to work for me (running iOS 17.4).

Alternatively, I found a workaround of applying the .popoverTip modifier to the Button / NavigationLink label itself located inside the label closure of the button / link.

  Full Work!!!

      ToolbarItem(placement: .topBarTrailing) {
                Button {
                    // call function 
                } label: {
                    Label("New", systemImage: "gear")
                    .popoverTip(tip, arrowEdge: .top)
                }
                .buttonStyle(.plain)
            }

I have tried different permutation of the suggestions here, but for me neither Button nor Toggle display tooltips on visionOS 2 beta. .help also does not work, unfortunately.

Did anyone got them to work on that platform in a toolbar (mine is attached to a Volume)?

RealityView {
  ...
}
.toolbar {
            ToolbarItemGroup {
              ...
            }
}

This fixed it for me on iOS 26.2 in a glass toolbar

ToolbarItem(placement: .confirmationAction) {
    Button(action: {
        self.create()
    }, label: {
        Text("Start Here")
        .popoverTip(BrowseWebTip(), arrowEdge: .top)
    })
    .buttonStyle(.glassProminent)
    .disabled(webPage.url == nil)
}

I am still unable to make this work under iOS 26 using the combination with .tipBackgroundInteraction(.enabled).

Without this modifier, it could be solved by adding popoverTip to the label or adding button style. But this new interaction modifier breaks it completely. Have you found any solution to this?

ToolbarItem {
    Button {
        print("taptap")
    } label: {
        Text("Here")
    }
    .buttonStyle(.plain)
    .popoverTip(myTip, arrowEdge: .top)
    .tipBackgroundInteraction(.enabled)
}

This still appears to be an issue on iOS 26 and macOS 26.

For a control inside a navigation-bar ToolbarItem, the .buttonStyle(...) workaround is still required. In my case, the tip reaches .available and the isPresented binding flips to true, but nothing is rendered unless the enclosing control has an explicit button style.

Attaching .popoverTip(...) to the inner Label alone is not sufficient; the explicit button style is the important part. This works, and removing .buttonStyle(.plain) breaks presentation:

Toggle(isOn: $isOn) {
    Label("Voice", systemImage: "mic")
        .labelStyle(.iconOnly)
        .popoverTip(tip, isPresented: $isPresented, arrowEdge: .top)
}
.buttonStyle(.plain)
.toggleStyle(.button)

I’m also seeing a separate issue with the popoverTip(_:isPresented:...) overload on iOS 26/macOS 26: if the modifier remains attached while the tip value is nil, or after the tip is dismissed/no longer eligible, an empty popover shell can briefly appear and dismiss itself. This is especially visible on macOS.

The only reliable workaround I’ve found is to remove the .popoverTip(...) modifier from the view hierarchy entirely once the tip is no longer eligible, rather than passing nil:

if tipIsEligible {
    label.popoverTip(tip, isPresented: $isPresented)
} else {
    label
}

I’ve worked around both issues as best I can, but wanted to leave an update here for anyone else who lands on this thread while debugging TipKit + toolbar presentation, as I did.

TipKit: showing a popover tip on a SwiftUI toolbar button
 
 
Q