Passing Data with NavigationLink
Learn how to pass data from one view to another in SwiftUI when using a NavigationLink, enabling you to display dynamic content in your detail views.
Note:
This tutorial covers how to pass data to a detail view when a user taps on an item in a list, a fundamental pattern for master-detail interfaces.
Overview
We have previously seen different methods for transitioning between views in SwiftUI. In this article, we will not only transition to a different screen using NavigationView and NavigationLink, but we will also prepare and display data on the destination screen based on the user's selection.
References:
- SwiftUI Tutorial #2 — Navigating with NavigationView
- SwiftUI Tutorial #4 — Presenting Views with Sheets
Step 1: Create the Data Model
First, let's create our data model in a separate Swift file. We'll make a simple ToDo struct that is Identifiable so we can use it easily in a List.
// In ToDoModel.swift
import Foundation
struct ToDo: Identifiable {
let id = UUID()
let task: String
let description: String
}
// Sample data
let toDoList = [
ToDo(task: "Morning Walk", description: "Go for a 30-minute walk in the park."),
ToDo(task: "SwiftUI Practice", description: "Work on the new SwiftUI tutorial."),
ToDo(task: "Grocery Shopping", description: "Buy milk, eggs, and bread.")
]
Step 2: Create the Detail View
Next, let's create the view that will display the details of a selected ToDo item. This view, DetailView, will have a property to hold the ToDo object that is passed to it.
// In DetailView.swift
import SwiftUI
struct DetailView: View {
// This property will be initialized by the previous view
let selectedToDo: ToDo
var body: some View {
VStack(alignment: .leading, spacing: 10) {
Text(selectedToDo.task)
.font(.largeTitle)
.fontWeight(.bold)
Text(selectedToDo.description)
.font(.body)
Spacer()
}
.padding()
.navigationTitle("Task Details")
}
}
Step 3: Create the Main View and Pass Data
Finally, in our main ContentView, we will create a List that displays our to-do items. Each row in the list will be a NavigationLink.
The key part is in the NavigationLink's destination. We initialize our DetailView and pass the specific toDoItem from the ForEach loop to the selectedToDo property of the DetailView.
// In ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(toDoList) { toDoItem in
NavigationLink(destination: DetailView(selectedToDo: toDoItem)) {
Text(toDoItem.task)
}
}
}
.navigationTitle("To-Do List")
}
}
}
Now, when you tap on an item in the list, SwiftUI navigates to the DetailView and displays the correct task and description, because we passed the corresponding ToDo object during the initialization of the DetailView.
Note:
Passing data during the initialization of the destination view is the most common and straightforward way to create master-detail interfaces in SwiftUI using NavigationLink.