I select the systemImage "map" and "person" for the tabItem, but the images are in filled format which must be in hollow format. What's the reason?
struct TestView: View {
var body: some View {
TabView {
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
}
Text("Profile")
.tabItem {
Label("Person", systemImage: "person")
}
}
}
}
Xcode: 13.1
SF Symbols: 3.1
This is standard SwiftUI behaviour in iOS 15, as it implements by default the recommendations from Apple’s Human Interface Guidelines, which says tab bars should use filled variants of SF Symbols, while sidebars on iPad should use the outline variant.
The effect is achieved by iOS automatically applying the .symbolVariants
environment value, as noted in the symbol variants documentation:
SwiftUI sets a variant for you in some environments. For example, SwiftUI automatically applies the
fill
symbol variant for items that appear in the content closure of theswipeActions(edge:allowsFullSwipe:content:)
method, or as the tab bar items of a TabView.
If you absolutely want to get rid of the fill mode, it’s deliberately made tricky but not impossible. You have to override the supplied \.symbolVariants
environment variable directly on the Label
element, inside your tabItem
declaration:
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
.environment(\.symbolVariants, .none)
}
Using the .symbolVariants(.none)
modifier, or trying to set the environment value higher up the view graph, won’t work.
Now that you see how to override the effect, I would still advise using the filled forms in the tab bar. Given that the tab bar no longer has a background colour difference from the rest of the page in many cases, the extra visual weight given to tab items by use of the filled variant lends the right amount of visual weight to those elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With