user14305195
user14305195

Reputation: 859

UITabViewController in SwiftUI has its Tab's OnAppear Being Called Twice

I'm currently making use UITabBarController in SwiftUI. Here is the implementation:

struct MyTabView: View {

    private var viewControllers: [UIHostingController<AnyView>]

    public init( _ views: [AnyView]) {
        self.viewControllers = views.map { UIHostingController(rootView:$0) }
    }
    
    public var body: some View {
        return TabBarController(controllers: viewControllers)
            .edgesIgnoringSafeArea(.all)
    }

}

struct TabBarController: UIViewControllerRepresentable {

    var controllers: [UIViewController]

    func makeUIViewController(context: Context) -> UITabBarController {
        let tabBarController = UITabBarController()
        tabBarController.viewControllers = controllers
        return tabBarController
    }

    func updateUIViewController(_ tabBarController: UITabBarController, context: Context) { }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UITabBarControllerDelegate {
        var parent: TabBarController

        init(_ tabBarController: TabBarController) {
            self.parent = tabBarController
        }
    }
}

Inside of my SwiftUI I have the following:

struct ContentView: View {
    var body: some View {

        MyTabView([
            AnyView(Text("Moo Moo")),
            AnyView(MyPage())
        ])

        
    }
}

struct MyPage:View {

    var body:some View {
        
        NavigationView {
            
            VStack {
                ForEach((1...10).reversed(), id: \.self) { value -> AnyView in
                        print("For Each Value Called")
                    return AnyView(MyView(text: String(value)))
                }
            }
            
            
        }
    }
    
}

struct MyView:View {
 
    let text:String

    var body:some View {
        Text(text).onAppear {
            print("On Appear Called - Making Service Call for \(text)")
        }
    }
    
}

I have the following questions:

  1. When running this code the On Appear Called - Making Service Call for \(text), is called twice. What would cause this? My expectation is that it is only run once. Should this be occurring?
  2. Is this a SwiftUI bug lurking around or is this expected behaviour?

Upvotes: 2

Views: 665

Answers (2)

Rolando Pusineri
Rolando Pusineri

Reputation: 57

maybe I found a solution: add on every very first NavigationLink the modifier .isDetailLink(false) for me it stops the double onAppear calls

Upvotes: 0

davidev
davidev

Reputation: 8517

  1. Yes, your expectation would be correct. However, it looks like a bug.

The problem appear when having content inside NavigationView. If you use .onAppear() on the NavigationView, you will see it called only once. If you use onAppear() on the VStack, it's already twice.

This has reported in this thread aswell

  1. From my view, this behavior is wrong. Maybe report to Apple or ask why

Upvotes: 1

Related Questions