1

I am having trouble updating values in an array that are displayed via a for each loop. These values are displayed in a text field.

The code in question

struct EditItemView: View {


@State var recipeStep: [String]
@State var stepInfo: String = ""
@State var textFieldCount: Int = 1
@State var stepNumber: [Int]
@State var recordsCount = 2

var body: some View {
    //a bunch of code between here and the list, does not apply
    VStack {
        List {
                ForEach(0..<recipeStep.count, id: \.self) { index in
                            HStack {
                                Text(String(stepNumber[index]) + ".").bold()
                                EditorViewEdit(container: self.$recipeStep, index: index, text: recipeStep[index])
                            }
                }.onDelete { (indexSet) in
                    stepNumber.remove(atOffsets: indexSet)
                    recipeStep.remove(atOffsets: indexSet)
                }

The following piece of code in the ForEach loop is what I use to make each of the text fields editable in the list (as I do not know of any other way to make text fields work in a list):

EditorViewEdit(container: self.$recipeStep, index: index, text: recipeStep[index])

The struct referenced in the above code can be seen below:

struct EditorViewEdit : View {
var container: Binding<[String]>
var index: Int

@State var text: String

var body: some View {
    TextField("", text: self.$text, onCommit: {
        self.container.wrappedValue[self.index] = self.text
    })
}

}

The Question

How can I make a change to a textfield in a foreach loop and have its value in @State var recipeStep: [String] be updated accordingly? For example, I edit the first TextField in the for each loop - how can I update index 0 in the array with its new value?

Ken White
  • 123,280
  • 14
  • 225
  • 444
nickreps
  • 903
  • 8
  • 20

1 Answers1

1

there are many ways to make a change to a textfield in a foreach loop and have its value in recipeStep. Try something like this:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var recipeStep = ["recipe step 1","recipe step 2","recipe step 3"]
    var body: some View {
        VStack {
            EditItemView(recipeStep: $recipeStep)
            Text(recipeStep.description) 
        }
    }
}

struct EditItemView: View {
    @Binding var recipeStep: [String]
    
    var body: some View {
        VStack {
            List {
                ForEach(recipeStep.indices, id: \.self) { index in
                    HStack {
                        Text(String(index) + ".").bold().foregroundColor(.red)
                        TextField("Recipe step", text: $recipeStep[index])
                    }
                }.onDelete { indexSet in
                    recipeStep.remove(atOffsets: indexSet)
                }
            }
        }
    }
}