The setup is quite simple:
- State/Observable/Computet property, let's call it
S1 - Views (
V1,V2) that depend onS1
The following conditions must hold:
V1should have a transition for in/out and be animated- Other views (e.g.
V2) must not be animated whenS1changes V2is animatable by other states (e.g.S2)
Some consequences:
- Using
withAnimation { .. }onS1would also lead to animatingV2unless animation is disabled here using.animation(nil). - However,
V2.animation(nil)is not an option, because they still need to be animatable by the other state variableS2. - I therefore ruled out
withAnimation { .. }
I prepared the following example:
struct Test: View {
@State private var S1: Bool = false
@State private var S2: Bool = false
func VX(_ text: String, color: Color = .red) -> some View {
Text(text).padding(10).background(color).padding(10)
}
var transition: AnyTransition {
.move(edge: .top).combined(with: .opacity)
}
var body: some View {
VStack {
if S1 {
VX("V1")
.transition(transition)
.animation(.easeOut, value: S1) // <--- not working
}
VX("V2", color: S2 ? .red : .blue)
.offset(x: S1 ? 30 : 0)
Spacer()
HStack {
Button(action: changeS1) {
Text("Change S1")
}
Button(action: changeS2) {
Text("Change S2")
}
}
}
}
func changeS1() {
S1.toggle()
}
func changeS2() {
S2.toggle()
}
}
I think they way I implement the animation doesn't work because the view is conditionally inserted by the same variable and thus not present at the time where the value (S1) is changing thus .animation(.., value: S1) cannot detect any changes and thus no animation occurs.
So the question is: How to animate a view's transition based on a variable that determines it's conditional presence at the same time?
Any ideas are appreciated - thanks!
The
.animationmodifier should be applied to a container owning conditional view, so it could animate appear/disapper transition, like