How to modify data inside array in SwiftUI

Issue #516

Suppose we have an array of SearchObject, and user can enter search query into text property.

1
2
3
4
5
6
7
8
9
10
class SearchObject: ObservableObject {
let name: String
let search: (String) -> [Country]
var text: String = ""

init(name: String, search: @escaping (String) -> [Country]) {
self.name = name
self.search = search
}
}

Although SearchObject is class, when we use ForEach, the changes to passed object won’t be reflected in our array and there is no reload trigger, we need to point to object in array directly, like

1
self.$searchObjects[index].text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct SearchScreen: View {
@State var searchObjects: [SearchObject] = [
SearchObject(name: "By name", search: { CountryManager.shared.search(byName: $0) }),
SearchObject(name: "By calling code", search: { CountryManager.shared.search(byCallingCode: $0) }),
SearchObject(name: "By domain", search: { CountryManager.shared.search(byDomain: $0) }),
SearchObject(name: "By language", search: { CountryManager.shared.search(byLanguage: $0) })
]

var body: some View {
ScrollView {
VStack(alignment: .leading) {
ForEach(searchObjects.enumerated().map({ $0 }), id: \.element.name, content: { index, searchObject in
VStack(alignment: .leading) {
Text(searchObject.name)
.styleLabel()
TextField(searchObject.textFieldName, text: self.$searchObjects[index].text)
.styleTitle()
self.makeButton(searchObject: self.searchObjects[index])
}
})
}
}
}
}

Comments