3

The navigationDestination is being called a single time when using an array of type (ie: [String]) but multiple times when using NavigationPath after an append.

Check it with a breakpoint on Text(string) and switching the path types.

Tested with:

  • iOS 16.1 - Xcode 14.0 & 14.1
  • iOS 16.4.1 - Xcode 14.3
  • iOS 16.5 - Xcode 14.3

Code:

import SwiftUI

struct ContentView: View {
    
    @State private var path = NavigationPath()
//    @State private var path = [String]()
    
    var body: some View {
        NavigationStack(path: $path) {
            VStack {
                Button("append") {
                    path.append("string")
                }
            }
            .navigationDestination(for: String.self) { string in
                Text(string) // <--- breakpoint here
            }
        }
    }
}
4
  • Filled FB11757519 - NavigationStack with NavigationPath calling navigationDestination multiple times.
    – JS1010111
    Nov 5, 2022 at 22:19
  • Issue ack'd by an Apple DTS engineer and forwarded to the SwiftUI team.
    – JS1010111
    Nov 16, 2022 at 13:16
  • is there any work around for this?
    – Kraming
    Dec 6, 2022 at 6:39
  • @Kraming, just posted a suggest workaround from the DTS engineer. FB11757519 is still in Open status.
    – JS1010111
    Dec 7, 2022 at 19:35

2 Answers 2

2

This is a workaround suggested by an Apple DTS engineer that may be useful (does not solve all cases depending on your navigation/views structure).

import SwiftUI

struct Model: Hashable {
    var intValue: Int
    var stringValue: String
    
    init(_ value: Int) {
        intValue = value
        stringValue = value.description
    }
}

struct ContentView: View {
    @State private var path = NavigationPath()
    @State private var models: [Int: Model] = [:]
    
    var body: some View {
        NavigationStack(path: $path) {
            VStack {
                Button("append") {
                    path.append(Int.random(in: 0...100))
                }
            }
            .navigationDestination(for: Int.self) { int in
                let model = model(for: int)
                Text(model.stringValue)
            }
        }
    }
    
    func model(for int: Int) -> Model {
        if let string = models[int] {
            return string // <--- breakpoint here
        } else {
            let model = Model(int)
            models[int] = model
            return model // <--- breakpoint here
        }
    }
}
1
  • 2
    so basically it just stop creating view model object again and again but the calling would be multiple times. Thanks for letting me know.
    – Kraming
    Dec 12, 2022 at 8:51
1

It's fixed!

Tested with beta 8 of Xcode 15 and iOS 17.

1
  • Not for my very similar case, it isn't. The closure is being called three times. Xcode 15, iOS 17, I'm using a Hashable enum instead of Int
    – andbi
    Sep 29, 2023 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.