SwiftUI onAppear called multiple times because of NavigationLink

Viewed 2069

SwiftUI onAppear gets called multiple times when inside of a navigation link. In the example I have provided, it gets called 5 times. This also triggers its StateObject initializer to get called 5 times as well. If you comment the Navigation Link out, it performs as expected.

This has been tested with both Xcode 12 GM and Xcode 12.2 with iOS 14 GM and iOS 14.2 beta 1. Also filed as feedback FB8721761.

struct ContentView: View {
    var body: some View {
        NavigationLink(destination: Color.red, label: {
            ImageView()
                .frame(width: 166.66, height: 250)
                .cornerRadius(10)
        })
    }
}

struct ImageView: View{
    @StateObject private var downloader = Downloaded(url: URL(string: "https://image.tmdb.org/t/p/w342/TnOeov4w0sTtV2gqICqIxVi74V.jpg")!)

    var body: some View{
        Rectangle()
            .onAppear{
                print("Appeared")
            }
    }
}

class Downloaded: ObservableObject{
    var cancellable: AnyCancellable?
    let url: URL

    init(url: URL){
        self.url = url
        download()
    }

    func download(){
        cancellable = URLSession.shared.dataTaskPublisher(for: url)
            .map(\.data)
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
            .sink(receiveCompletion: { _ in
                print("Finished downloading")
            }, receiveValue: {_ in})
    }
}
2 Answers

I filed a feedback with Apple and this has been resolved in iOS 14.2 beta 3.

This is the solution that works for me. There should be only one root NavigationView, if you put parent and child NavigationView then onAppear called multiple times

Related