I have two views in a TabView, which are Page1 and Page2. The two pages have the same view in common: AnimatingText. Page2 has an additional button that starts the animation of AnimatingText.
When I tap the button in Page2, I expected the animation would start simultaneously in both Page1 and Page2. However, I found that the animation in Page1 is delaying until I switch back to Page1.
I assume this behavior is by design. But I want to implement any of the following behaviors (both are fine for me):
- When I tap the button in
Page2, the animation ofAnimatingTextstarts at the same time inPage1andPage2. - When I tap the button in
Page2, the animation ofAnimatingTextstarts inPage2. When I switch back toPage1,AnimatingTextis rerendered with the new state without animation.
Is there any workaround that I can try? Thanks.
Code
import SwiftUI
struct AnimationTestView: View {
@State var startAnimate: Bool = false
var body: some View {
TabView {
Page1(startAnimate: $startAnimate)
.tabItem {
Text("page1")
}
Page2(startAnimate: $startAnimate)
.tabItem {
Text("page2")
}
}
}
}
struct AnimatingText: View {
@Binding var startAnimate: Bool
var body: some View {
VStack{
Text("text1")
if startAnimate {
Text("text2")
}
Text("text3")
}
}
}
struct Page1: View {
@Binding var startAnimate: Bool
var body: some View {
AnimatingText(startAnimate: $startAnimate)
}
}
struct Page2: View {
@Binding var startAnimate: Bool
var body: some View {
ZStack {
AnimatingText(startAnimate: $startAnimate)
VStack {
Spacer()
Button {
withAnimation(.easeInOut(duration: 1)) {
startAnimate.toggle()
}
} label: {
Text("tap here to animate view in page1")
}
}
}
}
}
struct AnimationTestView_Previews: PreviewProvider {
static var previews: some View {
AnimationTestView()
}
}
CodePudding user response:
- When I tap the button in Page2, the animation of AnimatingText starts at the same time in Page1 and Page2.
I'd say it is impossible with built-in animation engine - there is nothing actually to animate till Page1 goes to screen.
- When I tap the button in Page2, the animation of AnimatingText starts in Page2. When I switch back to Page1, AnimatingText is rerendered with the new state without animation.
It is much simpler goal, just make animation explicitly local, like
var body: some View {
ZStack {
AnimatingText(startAnimate: $startAnimate)
VStack {
Spacer()
Button {
startAnimate.toggle() // << just toggle state
} label: {
Text("tap here to animate view in page1")
}
}
}
.animation(.easeInOut(duration: 1), value: startAnimation) // local animation !!
}
