In this comprehensive tutorial, we’ll guide you through the process of constructing a fully functional…
How to display sample SwiftData in SwiftUI with PreviewModifier

In this tutorial, we will explore how to display sample SwiftData in SwiftUI with PreviewModifier
Step 1: Define the Entity
First, we need to define a Task entity that we will use to store our task data in SwiftData.
import Foundation
import SwiftData
@Model
class Task {
@Attribute(.unique) var id: UUID
var title: String?
var isCompleted: Bool
init(id: UUID = UUID(), title: String? = nil, isCompleted: Bool = false) {
self.id = id
self.title = title
self.isCompleted = isCompleted
}
}
In this code, we define the Task model with an id, title, and isCompleted property. The @Model attribute is used to make this class a SwiftData model.
Step 2: Create the Task List View
Next, we’ll create a SwiftUI view that displays a list of tasks, each with a toggle for marking them as completed or not.
import SwiftUI
import SwiftData
struct TaskListView: View {
@Query(sort: \Task.title) private var tasks: [Task]
@Environment(\.modelContext) private var context
var body: some View {
List {
ForEach(tasks) { task in
HStack {
Text(task.title ?? "")
.font(.title2)
.foregroundColor(task.isCompleted ? .green : .black)
Spacer()
Toggle("", isOn: Bindable(task).isCompleted)
}
}
.onDelete(perform: deleteTask)
}
.task {
for task in sampleTasks {
context.insert(task)
}
}
.navigationTitle("Tasks")
}
private func updateTaskCompletion(_ task: Task, newValue: Bool) {
task.isCompleted = newValue
try? context.save()
}
private func deleteTask(at offsets: IndexSet) {
for index in offsets {
context.delete(tasks[index])
}
try? context.save()
}
}
In this view, each task can be marked as completed by toggling a switch, and we handle saving this state with SwiftData.
Step 3: Preview with SwiftData Context
To make the preview functional, we need to set up a SwiftData context. We’ll use the PreviewModifier protocol to create a shared context that holds some sample data.
import Foundation
import SwiftUI
import SwiftData
let sampleTasks = [
Task(title: "Buy Groceries"),
Task(title: "Walk the Dog", isCompleted: true),
Task(title: "Complete SwiftUI Project")
]
struct SampleTaskData: PreviewModifier {
static func makeSharedContext() throws -> ModelContainer {
let container = try ModelContainer(for: Task.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
for task in sampleTasks {
container.mainContext.insert(task)
}
return container
}
func body(content: Content, context: ModelContainer) -> some View {
content.modelContainer(context)
}
}
extension PreviewTrait where T == Preview.ViewTraits {
static var sampleTaskData: Self = .modifier(SampleTaskData())
}
In this example, the SampleTaskData struct conforms to PreviewModifier, providing a shared SwiftData context with in-memory tasks for the preview.
Step 4: Add a Preview #Preview(traits:
Now, let’s create a dynamic preview
#Preview(traits: .sampleTaskData) {
TaskListView()
}
Step 5. Add @Previewable to Preview
Now, we’ll use the @Previewable attribute inside the #Preview macro to interact with the Task completion status dynamically.
#Preview("Dynamic Task Preview") {
@Previewable @State var isTaskCompleted = false
let sampleTask = Task(title: "Complete SwiftUI Project", isCompleted: isTaskCompleted)
return HStack {
Text(sampleTask.title ?? "")
.font(.title2)
.foregroundColor(sampleTask.isCompleted ? .green : .black)
Spacer()
Toggle("", isOn: $isTaskCompleted)
}
}
In this preview:
- The
@Previewableattribute tags theisTaskCompletedstate variable. - This allows you to toggle the state of
isTaskCompleteddirectly in the Xcode preview and see real-time changes. - The task’s completion status will update dynamically as you interact with the toggle in the preview.
This tutorial demonstrated how to display sample SwiftData in SwiftUI with PreviewModifier and @Previewable
