I want to create a UI that allows me to create an arbitrary list of strings. For this, I have created a UI that has a button to append strings to a String Array. I also want to be able to arbitrarily remove any of the strings, so I have another button next to each element that removes it from the array. If I use a simple `Text` view, everything works just fine; however, if I change to using a `TextView` to allow the user to change the value, then I get an "index out of range" error when trying to remove an element from the array. Digging in it looks like although the element is removed from the array, the view acts as if it hasn't been removed. I'm not sure if I'm doing something wrong or if this is a bug.
To reproduce:
1. Create an iOS project with SwiftUI
2. Replace the default ContentView.swift code with the following:
import SwiftUI
struct ContentView : View {
@State var myList: [String] = []
var body: some View {
VStack(alignment: .leading) {
AppendButton(myList: $myList)
ListView(myList: $myList)
Spacer()
}
}
}
struct AppendButton: View {
@Binding var myList: [String]
var body: some View {
HStack {
Button(action: { self.myList.append("List Item") }) {
Image(systemName: "plus")
.padding()
}
.foregroundColor(.black)
.background(Color(.sRGB, white: 0.84, opacity: 1))
.cornerRadius(5.2)
Text("Add Item")
Spacer()
}
}
}
struct ListView: View {
@Binding var myList: [String]
var body: some View {
VStack(alignment: .leading) {
ForEach(0..<myList.count) { index in
HStack {
Button(action: { self.myList.remove(at: index) }) {
Image(systemName: "minus")
.padding()
}
.foregroundColor(.black)
.background(Color(.sRGB, white: 0.84, opacity: 1))
.cornerRadius(5.2)
//Text("\(self.myList[index]) \(index)")
TextField(self.$myList[index])
}
.padding(.leading)
}
}
.padding(.leading)
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif3. Run the app in the simulator
4. Click the plus button next to "Add Item" once or a few times
5. Click the minus button next to a "List Item"
I expect it to remove the item, but the app will crash with the "index out of range" bug. If you comment out the "TextField" line and uncomment the corresponding "Text" field instead, the application works just fine. Again, by breaking various pieces out, I've determined that the "ForEach" view runs one-to-many times for some reason which results in the "index out of range". (The issue isn't that the index is out of range in the button action that removes the item — that succeeds just fine.)