TL;DR
How do I get this Label("something", systemImage: "star").labelStyle(state ? .iconOnly : .titleAndIcon)
behaviour without losing the view identity of the label?
Full question
I want to conditionally apply a view style to a view. For example, based on a state I want to display labels with icons only or with icons and text like this:
struct DemoView: View {
@Binding var state: Bool
var names: [String]
var body: some View {
List(names) { name in
Label(name, systemImage: "star")
.labelStyle(state ? .iconOnly : .titleAndIcon) // erroneous line
}
}
}
However, because .iconOnly
and .titleAndIcon
do not share a type, the example above does not work. What is the correct way to solve this issue? I am explicitly looking for a way to solve the issue that does not mess with the Label
identity of the view. I have seen a lot of suggestions like the one below:
struct DemoView: View {
@Binding var state: Bool
var names: [String]
var body: some View {
List(names) { name in
if state {
Label(name, systemImage: "star")
.labelStyle(.iconOnly)
} else {
Label(name, systemImage: "star")
.labelStyle(.titleAndIcon)
}
}
}
}
The problem with this solution is, that the view identity of the Label
gets lost when the state changes. This causes issues with animations, for example. (The same is true for the very un-swifty .if(...)
view modifier “solution” that is floating around various threads.)
So, how do I conditionally apply different styles (which differ in their type signature) to a view without losing the view’s view identity?
dual0j is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2