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.

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

self.$searchObjects[index].text
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])
                    }
                })
            }
        }
    }
}
Written by

I’m open source contributor, writer, speaker and product maker.

Start the conversation