Reputation: 861
I would like to create a transition whose removal depends on a @State
value when the view is removed.
Here is what I have tried.
If isValid
is true when the view appears, it will use .move(edge: .trailing)
for removal, even if isValid
becomes false in the meantime.
What I try to obtain is .move(edge: .leading)
transition if isValid
is false
when the view is removed, even if it was true
when the view was inserted.
The problem appears when I toggle show
and isValid
at the same time.
struct TextTransitionView: View {
@State var isValid = false
@State var show = false
var body: some View {
VStack {
Spacer()
if show {
Text("TEXT").transition(slideTransition)
}
Spacer()
Text("Move to \(isValid ? "right" : "left")")
Button("Toggle isValid") {
self.isValid.toggle()
}
Button("Toggle show") {
withAnimation { self.show.toggle() }
}
Button("Toggle isValid and show") {
withAnimation {
self.isValid.toggle()
self.show.toggle()
}
}
}
}
var slideTransition: AnyTransition {
let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
return .asymmetric(insertion: .identity, removal: removal)
}
}
Upvotes: 2
Views: 143
Reputation: 861
The problem was with isValid.toggle()
being inside the withAnimation
. Getting this line out of the withAnimation
block solved the problem.
Button("Toggle isValid and show") {
self.isValid.toggle()
withAnimation {
self.show.toggle()
}
}
Upvotes: 0
Reputation: 8091
do you mean like so?
struct ContentView: View {
@State var isValid = false
var slideTransition: AnyTransition {
let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
return .asymmetric(insertion: .identity, removal: removal)
}
var body: some View {
VStack {
Button(action: {
withAnimation() {
self.isValid.toggle()
}
}) {
Text("animate it")
}
if isValid {
Text("text").transition(slideTransition)
}
}
}
}
Upvotes: 0
Reputation: 257563
Here is possible approach. Tested with Xcode 11.4 / iOS 13.4
struct DemoTextTransition: View {
@State var isValid = false
@State var show = false
var body: some View {
VStack {
if show {
Text("TEXT").transition(slideTransition)
}
Button("Valid: \(isValid ? "True" : "False")") {
self.isValid.toggle()
}
Button("Test") {
withAnimation { self.show.toggle() }
}
}
}
var slideTransition: AnyTransition {
let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
return .asymmetric(insertion: .identity, removal: removal)
}
}
Upvotes: 1