1

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
Wolfer
  • 11
  • 2

0 Answers0