tezvyn:

Map Data to Views Using navigationDestination

AI-drafted, machine-checkedintermediate

navigationDestination turns NavigationStack into a router: register a view per data type, then push raw values. It frees view models from creating views. Using it outside NavigationStack or mixing it with old NavigationLink destinations silently breaks…

WHY IT EXISTS: Before iOS 16, SwiftUI navigation relied on NavigationLink creating destination views at the call site. This tightly coupled data, view model logic, and view construction. It made programmatic navigation from view models awkward, broke deep linking, and forced reusable rows to know about screens they should not care about. navigationDestination was introduced to separate the act of navigating from the construction of the destination, enabling true data-driven routing inside NavigationStack.

THE MENTAL MODEL: Think of a NavigationStack as a shipping dock. In the old world, every package had to contain the finished product inside. With navigationDestination, the dock has assembly instructions indexed by package label. You hand the dock a lightweight label, a raw data value, and the stack looks up the instructions to build the correct view on demand. The source of the package never needs to know what gets built.

HOW IT WORKS: You attach the modifier to a view inside a NavigationStack, typically the stack's root view. The signature takes a type and a view builder closure. When a NavigationLink is triggered with a value of that type, or when a value is appended to a NavigationPath, the stack queries the registered factory and pushes the resulting view. Multiple navigationDestination modifiers can be chained for different types. SwiftUI matches the concrete type at runtime.

WHEN TO USE IT: Use it whenever navigation should be driven by state rather than view hierarchy. This includes MVVM architectures where a view model appends an enum case or model object to a path, deep linking that translates a URL into a typed value, and reusable components like list rows that only emit an identifier or model object without importing the detail view.

WHEN NOT TO USE IT: Do not use it if you still target iOS 15 or earlier, because NavigationStack and navigationDestination require iOS 16, macOS 13, tvOS 16, or watchOS 9. Do not use it inside a legacy NavigationView; the modifier is designed for NavigationStack and will silently fail or behave unpredictably in the old container. Avoid mixing it with NavigationLink initializers that take a destination view closure, because the stack may ignore one route system in favor of the other.

ONE CANONICAL EXAMPLE: Imagine a Mail app built with NavigationStack. The root view is a list of email summaries. Each row contains a NavigationLink with an email ID as its value. On the NavigationStack, you apply navigationDestination for UUIDs that instantiates EmailDetailView. A search handler in the view model can then append a UUID to the path array and the stack automatically pushes the detail view, even though the search UI never imports EmailDetailView.

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.