skip to Main Content

Since Swift 5.5 we could create SwiftUI lists with bindings like this (e.g. see this answer):

class Item {
    // ...
    var isOn: Bool
}

struct ContentView: View {
    @State private var items: [Item] = []
    var body: some View {
        NavigationView {
            List {
                ForEach($items) { $item in     // <--- list binding
                    Toggle(isOn: $item.isOn) {
                        Text("Vibrate on Ring")
                    }
                }
            }
        }
    }
}

Now I want to do something similar with SwiftData but I get an error:

struct ContentView: View {
    @Environment(.modelContext) private var modelContext
    @Query private var items: [Item]
    var body: some View {
        NavigationView {
            List {
                ForEach($items) { $item in //   <--- Cannot find '$items' in scope
    // ...

How can I render a list of SwiftData objects that allows inline editing of objects through bindings?

2

Answers


  1. The easiest solution I found is to use @Bindable and to separate the Query macro and the Bindable into different views.

    An example

    struct ItemRow: View {
        @Bindable var item: Item
       
        var body: some View {
            HStack {
                Text(item.name)
                Toggle(isOn: $item.isOn) // Notice the $
            }
        }
    }
    

    Calling view

    struct ContentView: View {
        @Environment(.modelContext) private var modelContext
        @Query private var items: [Item]
        var body: some View {
            NavigationView {
                List {
                    ForEach(items) { item in
                        ItemRow(item: item)
         //...
    }
    
    Login or Signup to reply.
  2. You can utilize the new Bindable, which has a subscript operator to wrap the underlying data into a binding variable:

    ForEach(items) { item in
        Toggle(isOn: Bindable(item).isOn) { ... }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search