TipKit styles its tips through environment-propagated modifiers: quick knobs for radius, image
size, and background, plus tipViewStyle for a fully custom layout. Each applies to every tip in
the hierarchy below it.
The Quick Knobs
List {
TipView(FeedTip.add)
// rows
}
.tipCornerRadius(8, antialiased: true)
.tipImageSize(CGSize(width: 24, height: 24))
.tipBackground(Material.regular)
tipCornerRadiusrounds every tip view in the child hierarchy.tipImageSizesizes the tip's image when theTipconformance defines one.tipBackgroundaccepts anyShapeStyle, a material here.
A Fully Custom Style
Conform to TipViewStyle and implement makeBody. The configuration hands you the tip's
optional image, title, and message plus its actions, and you lay them out with ordinary
SwiftUI.
struct MyCustomTipViewStyle: TipViewStyle {
func makeBody(configuration: Configuration) -> some View {
VStack(alignment: .leading) {
HStack(alignment: .firstTextBaseline) {
if let image = configuration.image {
image
}
VStack(alignment: .leading) {
if let title = configuration.title {
title.font(.headline)
}
if let message = configuration.message {
message.font(.subheadline)
}
}
}
HStack {
ForEach(configuration.actions, id: \.id) { action in
Button {
action.handler()
} label: {
action.label()
}
}
}
}
.padding()
}
}
Applying the Style
Add a static accessor for a clean call site, then set the style once; the environment carries it to every tip below, popover tips included.
extension TipViewStyle where Self == MyCustomTipViewStyle {
static var custom: Self { .init() }
}
List { /* content with popoverTip */ }
.tipViewStyle(.custom)