Did Apple really remove the ability to handle navigation with enums outside of List views in iOS 16?

In iOS 15 you used to be able to do something like they do in the Fruta sample SwiftUI app:

Define an enum which will hold which screen the user is currently in

enum NavigationItem {
    case menu
    case favorites
    case recipes
}

And then add links in your app to modify the current screen enum, triggering a screen transition.

NavigationLink(tag: NavigationItem.menu, selection: $selection) {
    SmoothieMenu()
} label: {
    Label("Menu", systemImage: "list.bullet")
}

The problem is that migrating to iOS16 Swift now warns me with:

'init(tag:selection:destination:label:)' was deprecated in iOS 16.0: use NavigationLink(value:label:) inside a List within a NavigationStack or NavigationSplitView

Did Apple really decide to force us to chose between containing all our links inside Lists and not using enums to define the current screen? It seems overly restrictive for no reason and forces me to write some really ugly hacks to have stand-alone links that don't belong to a list.

Replies

I built the Fruta project (including such an enum and NavigationLink API) with 16.2 target with Xcode 14.2. No issue. Except the need to add an empty Scene Configuration dictionary entry in info.plist to silence a warning.

Which versions of Xcode and iOS target do you use ?

Hi there!

You'll want to use the NavigationLink(value:label:) initializer along with NavigationStack and the navigationDestination(for:destination:) view modifier. The Discussion section of the navigationDestination documentation has an example. WWDC22's "What's New in SwiftUI" also discusses NavigationStack and and demonstrates updating your existing code to use it.