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
            }
        }
    }
}
JS1010111
  • 341
  • 2
  • 12

1 Answers1

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
        }
    }
}
JS1010111
  • 341
  • 2
  • 12
  • 1
    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 '22 at 08:51