SwiftUI onAppear called twice when NavigationView inside TabView
Asked Answered
D

1

7

So I have a TabView where each of the tabs is embedded in a NavigationView. On first appear of each tab I get the following lifecycle calls onAppear(), onDisappear(), onAppear(). So it looks like onAppear gets called twice. This only happens the first time. If I navigate back to the same tab, only onAppear() gets called, and only once.

Here's a minimal example:

struct Page1: View {
    init() { print("Page 1 init") }
    
    var body: some View {
        NavigationView {
            Text("Page 1")
                .onAppear(perform: { print("Page 1 appearing") })
                .onDisappear(perform: { print("Page 1 disappearing") })
        }
    }
}

struct Page2: View {
    init() { print("Page 2 init") }
    
    var body: some View {
        NavigationView {
            Text("Page 2")
                .onAppear(perform: { print("Page 2 appearing") })
                .onDisappear(perform: { print("Page 2 disappearing") })
        }
    }
}

struct ContentView: View {
    var body: some View {
        TabView {
            Page1().tabItem { Text("Page 1") }
            Page2().tabItem { Text("Page 2") }
        }
    }
}

And here's the result printed out:

Page 1 init
Page 2 init
Page 1 appearing
Page 1 disappearing
Page 1 appearing

Here's what happens if I click on the second tab

Page 1 init
Page 2 init
Page 1 appearing
Page 1 disappearing
Page 1 appearing
// here I clicked on second tab
Page 2 appearing
Page 2 disappearing
Page 2 appearing
Page 1 disappearing
Distinction answered 11/5, 2021 at 9:16 Comment(1)
I've seen the same behavior: onAppear is called more than once. I have no clue why that's the case, but I've worked around it by storing a boolean in the view and adding a condition in onAppear. So, if needOnAppear { needOnAppear = false }Pinnace
A
0
    TabView {
        NavigationView {
            VStack {
                Color.red
                    .onAppear {
                        print("appear : red")
                    }
                    .onDisappear {
                        print("disappear : red")
                    }
            }.onAppear {
                print("appear")
            }
        }
    }

Test on iOS 15 beta Simulator

The output:

appear : red
appear
disappear : red
appear : red
Agonistic answered 23/8, 2021 at 1:57 Comment(1)
you have a single tab inside the tabview. The problem arises when you switch between two tabsDistinction

© 2022 - 2024 — McMap. All rights reserved.