Colouring the arrow of a Popover in SwiftUI

Development / iOS / Making of Captionista

If you have custom background colours or e.g. force dark mode on your View as we do in Captionista, you will be sad to discover that the popover in SwiftUI draws the arrow without allowing you to colour it. If you use a NavigationView this is hidden from you as the navigation bar “fills” the arrow space also, but if you don’t… you end up with the system background colour in the arrow, and your custom colour in the body of the popover.

So for example using a specific dark background in your popover View you will see an ugly white callout arrow pointing at the element that triggered the popup.

Workaround: (SwiftUI 2) Hack the background to be bigger than infinity using negative padding (thanks to @naxum for the tip here, I originally used a GeometryReader):


struct PopoverView: View {
    var body: some View {
        Text("I am a popover! Now with a coloured arrow")
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(
            Color.blue
            .padding(-80) // <- expand the background outward
        )
    }
}

Yes, this one has a Feedback: FB8889301 “SwiftUI popover does not have a way to colour the callout arrow”

The Author

Marc Palmer (Threads, Mastodon) is a consultant and software engineer specialising in Apple platforms. He currently works on the iOS team of Concepts sketching app, as well as his own apps like screenshot framing and backgrounds app Shareshot and video subtitling app Captionista. He created the Flint open source framework that people liked the idea of but nobody uses. You can find out more here.