The issue with Conditional View Modifiers
I made heavy use of conditional view modifiers in SwiftUI until I had some issues with it and recently discovered it is a bad idea.
From my understanding now, doing something like this:
if condition {
view
} else {
view.hidden()
}
means that SwiftUI will treat view
in both cases as completely different views. So if you jump from if to else or vice versa, view is recreated, including running onAppear
and any initial animations. Besides that, it also breaks animating view
from one branch into the other. Even adding .id()
doesn’t seem to solve this.
I attached a minimum viable example so you can see this behaviour for yourself. And needless to say, this is bad. It has major performance implications, breaks animations and is even worse if you perform some heavy operation (like a network request) in your onAppear
.
The solution?
The solution appears to be to do something like this:
view.padding(condition? 10 : 0)
Everything works peachy, SwiftUI keeps view
around, great.
The problem: .isHidden()
Now, I need to conditionally hide a view. And to be honest, I have no idea how to achieve it. .isHidden()
has no parameter to enable or disable it, so there is no way to use the same approach as shown above.
So: How can I conditionally hide a view without recreating it? The reason I don’t want to recreate the view is that onAppear
gets called again and it reset the state of the view, triggering animations to the initial state again. Or am I using the wrong approach entirely in SwiftUI world here?
2
Answers
A possible approach is to use opacity+disabled, like
In SwiftUI a View struct is just data, SwiftUI is what diffs the data and decides what actual UIViews to add, remove, update on screen. So if you want to hide something just give it empty data, e.g.
It would be helpful to know what data it is you are trying to show/hide.