Search code examples
swiftuiswiftui-navigationstack

Why doesn't :contentsOf work when appending an array to NavigationPath object?


I have the following code:

@Published var path:[Screen] = []

var launchScreens:[Screen] = [.someOtherView, .launch]

init() {
    path.append(contentsOf: launchScreens)
}

It works as expected and appends launchScreens to my path variable. When I add other enum values, they are also added to the NavigationPath, and when bound to my NavigationStack, the other view show in the order added.

However; if I want to use a NavigationPath instead of a [Screen] (as below) I get an error that says "Extraneous argument label 'contentsOf:' in call"

@Published var path = NavigationPath()

var launchScreens:[Screen] = [.someOtherView, .launch]

init() {
    path.append(contentsOf: launchScreens)
}

If I remove the "contentsOf", the compiler doesn't complain, but the screens fail to load correctly. I'd like to use NavigationPath because I have different View types besides 'Screen' to add.

How can I append an array of views to NavigationPath?


Solution

  • NavigationPath simply does not have such a method. You need to call append multiple times, with a loop.

    You can write an extension like this

    extension NavigationPath {
        mutating func append<S: Sequence>(contentsOf sequence: S) where S.Element: Hashable {
            for elem in sequence {
                append(elem)
            }
        }
    }
    

    You should not think of NavigationPath as a "collection". It does not conform to any of the collection protocols like RangeReplaceableCollection.


    In this specific situation, since path is empty initially, you can also initialise path like this:

    @Published var path: NavigationPath
    
    var launchScreens:[Screen] = [.someOtherView, .launch]
    
    init() {
        path = NavigationPath(launchScreens)
    }
    

    This obviously wouldn't work if path is not empty, because it would overwrite the existing elements in path.