Error with: Binding, ForEach and TextField

I have been trying to use the new @Binding capabilities in SwiftUI but every time I make a ForEach and pass binding values, when the TextField changes, the keyboard unfocuses the Field.

struct ContentView: View {

    @State private var texts: [String] = ["Orange", "Apple"]

    

    var body: some View {

        NavigationView {

            List {

                ForEach($texts, id: \.self) { $text in

                    TextField("Fruit", text: $text)

                }

            }

            .navigationTitle("Fruit List")

        }

        .navigationViewStyle(.stack)

    }

}

That is what I have tried, is there an error in my implementation or is it just a bug?

My Mac:

  • MacMini 2020 - M1 16GB
  • Xcode 13.0 - (13A233)
  • Project Built - for iOS 15
  • Removed and replaced by next answer -

the keyboard unfocuses the Field.

Do you mean that the keyboard hides ? Effectively, it hides for fields in ForEach loop.

Using focused makes it work (just a glitch: keyboard hides and show at each typing: You should correct with an enum with case for each field -see Xcode doc for example-):

struct ContentView: View {

    enum FocusField: Hashable {
      case field
    }
    
    @State private var texts: [String] = ["Orange", "Apple"]
    @FocusState private var focusedField: FocusField?

    var body: some View {
        NavigationView {

            List {
                ForEach($texts, id: \.self) { $text in
                    TextField("Fruit", text: $text)
                        .focused($focusedField, equals: .field)
                        .task {
                          self.focusedField = .field
                        }
                }
            }
            .navigationTitle("Fruit List")
        }
        .navigationViewStyle(.stack)
    }

}

Credits:

func focused<Value>(_ binding: FocusState<Value>.Binding, equals value: Value) -> some View where Value : Hashable

May also look at the discussion here, explaining there is no responder chain in SwiftUI…https://stackoverflow.com/questions/56765187/how-do-i-update-a-list-in-swiftui

I guess, what is bad in your code is that TextField changes the value used as id:.

Please try something like this:

struct RowModel: Identifiable {
    let id = UUID()
    var name: String
}
struct ContentView: View {
    @State var rows: [RowModel] = [
        RowModel(name: "Orange"),
        RowModel(name: "Apple"),
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach($rows) { $row in
                    TextField("Fruit", text: $row.name)
                }
            }
            .navigationTitle("Fruit List")
        }
        .navigationViewStyle(.stack)
    }
}

It is not clearly documented how SwiftUI works, but with TextField changing the value used as id:, whole the row is redrawn which may cause the keyboard unfocuses the Field.

Error with: Binding, ForEach and TextField
 
 
Q