I'd like to see how I can make it so changes to a Text view's source change with a fade in and out.
So if I've got a simple view like the following:
struct TestView: View {
@State var text = "I am a shrubber."
func changeText() {
text = (text == "I am a shrubber.") ? "My name is Roger the Shrubber." : "I am a shrubber."
}
var body: some View {
VStack {
Text(self.text)
TestButton(label: "Change", action: changeText)
}
}
}
If I tap the button the text changes instantly.
Now, if I wrap the changing code in a withAnimation block, or add an .animation view modifier to the Text view, it just animates the change in the frame size. Which isn't what I'm looking for:
struct TestView: View {
@State var text = "I am a shrubber."
func changeText() {
withAnimation {
text = (text == "I am a shrubber.") ? "My name is Roger the Shrubber." : "I am a shrubber."
}
}
var body: some View {
VStack {
Text(self.text)
TestButton(label: "Change", action: changeText)
}
}
}
Of course, I could get close to the effect I'm looking for by using .transition view modifiers and separate text fields (this answer: https://stackoverflow.com/a/60984127/5919644), like this:
struct TestView: View {
@State var changed = false
var body: some View {
VStack {
if !changed {
Text("I am a shrubber.")
.transition(AnyTransition.opacity.animation(.easeInOut(duration:0.3)))
}
if changed {
Text("My name is Roger the Shrubber.")
.transition(AnyTransition.opacity.animation(.easeInOut(duration:0.3)))
}
TestButton(label: "Change", action: { self.changed.toggle() })
}
}
}
But that is terrible pattern and doesn't work with arbitrary text changes. And even then the fade in and out happen at the same time. I'd like to have the fade out/in happen sequentially.



