Skip to content
👩🏻‍💻 🧑🏽‍💻 Join us for Free for Full Access to site Content

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 @Previewable attribute tags the isTaskCompleted state variable.
  • This allows you to toggle the state of isTaskCompleted directly 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

This Post Has 0 Comments

Leave a Reply

Back To Top
Search

Get Latest App Development News, Tips and Tutorials

* indicates required