-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

SwiftUI Cookbook
By :

Editing lists has always been possible in SwiftUI but before WWDC 2021 and SwiftUI 3, doing so was very inefficient because SwiftUI did not support binding to Collections. Let's use bindings on a collection and discuss how and why it works better now.
Create a new SwiftUI project and name it EditableListsFields
.
Let's create a simple to-do list app with a few editable items. The steps are as follows:
TodoItem
struct below the import
SwiftUI line:struct TodoItem: Identifiable { let id = UUID() var title: String init(_ someTitle:String){ title = someTitle } }
ContentView
struct, let's add a collection of TodoItem
instances:@State var todos = [ TodoItem("Eat"), TodoItem("Sleep"), TodoItem("Code") ]
Text
view in the body with a List
and a TextField
view that displays the collection of todo
items:var body: some View { List($todos) { $todo in TextField("Number", text: $todo.title) } }
Run the preview in canvas. You should be able to edit the text in each row, as shown in the following screenshot:
Figure 2.10 – Editable Collections preview
Click on any of the other rows and edit it to your heart's content.
Let's start by looking at how editable lists were handled before SwiftUI 3. Before SwiftUI 3, the code for an editable list of items would use list indices to create bindings to a collection, as follows:
List(0..<todos.count) { index in TextField("Todo", text: $todos[index].title) }
Not only was such code slow, but editing a single item caused SwiftUI to re-render the entire List
of elements, leading to flickering and slow UI updates.
With SwiftUI 3, we can pass a binding to a collection of elements, and SwiftUI will internally handle binding to the current element specified in the closure. Since the whole of our collection conforms to the Identifiable
protocol, each of our list items can be uniquely identified by its id
parameter; therefore, adding or removing items from the list does not change list item indices and does not cause the entire list to be re-rendered.