I am trying to animate on a view’s onAppear method in a tabView, but the next view’s onAppear also executed, when the previous view is just appearing. Seems like the TabView preloads the following page, which triggers the animation before the next page is actually displayed.
Is there a better way to trigger an animation when the view is actually appearing for the user or the TabView’s preloading can be turned off somehow?
Here is a basic code example:
struct ContentView: View {
let pages = ["Page One", "Page Two", "Page Three", "Page Four", "Page Five", "Page Six"]
var body: some View {
TabView {
ForEach(pages, id: \.self) { pageTitle in
PageView(title: pageTitle)
}
}
.tabViewStyle(.page)
}
}
struct PageView: View {
@State private var isAnimating: Bool = false
let title: String
var body: some View {
Text(title)
.font(.title)
.scaleEffect(isAnimating ? 0.2: 1.0)
.onAppear {
print("onAppear - \(title)")
isAnimating = true
withAnimation(.easeOut(duration: 1.0)) {
isAnimating = false
}
}
.onDisappear() {
print("onDisappear - \(title)")
}
}
}
When page 2 is displayed the page 3’s on appear also triggered. Once the use actually swipes to the 3rd page, the animation is already concluded and no animation is visible.
Explained debug log:
App start:
onAppear - Page One
Swiping to page 2:
onAppear - Page Two
onAppear - Page Three
onDisappear - Page One
Swiping to page 3: (page 3 is NOT animated on the screen)
onAppear - Page Four
onDisappear - Page Two