Search code examples
swiftswiftui

Connecting TextField to each List item in SwiftUI


I'm really sorry to ask this silly question , but how do i assign the TextField to each item in the list? At the moment i understand that TextField is not connected to any of items hence when you add items and try to enter some input it's editing all the textfields at the same time. Thanks

> //CONTENT 
> 
> import SwiftUI
> 
> struct ContentView: View {
>     @StateObject private var vm = ViewModel()
>     @State private var textField = ""
>     @State private var localArray: [Item] = []
>     var body: some View {
>         VStack {
>             List(vm.itemList) { item in
>                 Text(item.name)
>                 TextField("Assign the value", text: $textField)
>             }
>             .listStyle(.plain)
>             .background(.thinMaterial)
>             Button("Add item") {
>                 vm.addItem()
>             }
>             .padding()
>         }
>     } }
> 
> #Preview {
>     ContentView() }
> 
> 
> // VIEW MODEL 
> 
> import Foundation import SwiftUI
> 
> extension ContentView {
>     @MainActor class ViewModel: ObservableObject {
>         
>         @Published var itemList = [Item]()
>         
>         let randomItems = ["Create a variables called greeting and assign the value Hello",
>                            "Create a constant called car and assign bmw to it",
>                            "Create an integer and assign number 25",
>                            "Create a double and assign 1.50"]
>        
>         func addItem() {
>             guard let item = randomItems.randomElement() else { return }
>             let newItem = Item(name: item)
>             withAnimation {
>                 itemList.insert(newItem, at: 0)
>             }
>         }
>     } }
> 
> 
> // MODEL 
> 
> import Foundation
> 
> struct Item: Identifiable, Codable {
>     var id = UUID()
>     var name: String
>     var description: String? }

Solution

  • Most likely you want to bind each text field to a property in Item for example description. Just delete

    @State private var textField = ""

    and change the List to

    List($vm.itemList) { $item in
        Text(item.name)                
        TextField("Assign the value", text: $item.description)
    }
    

    Note: In this case description must be non-optional.