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 ofAnimatingText
starts at the same time inPage1
andPage2
. - When I tap the button in
Page2
, the animation ofAnimatingText
starts inPage2
. When I switch back toPage1
,AnimatingText
is 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 !!
}