I'd like to have an extension on Array<T> that basically returns a Binding<T>.
The purpose of this would be to have a convenient way to create a Binding in DetailView that was called from a NavigationLink of a List.
Here's what I got so far:
extension Array where Element: Identifiable {
mutating func getBinding(of instance: Element) -> Binding<Element> {
if let index = self.firstIndex(where: { $0.id == instance.id }) {
return Binding(
get: { self[index] }, //error
set: { self[index] = $0}) //error
} else {
fatalError() //implement error handling here
}
}
}
I am getting the error Escaping closure captures mutating 'self' parameter at the specified places. How can I work around this?
TL;DR
Here's how I'd like to use this extension:
class ViewModel: ObservableObject {
@Published var items: [Item]
init(with items: [Item] = [Item]()) {
self.items = items
}
}
struct Item: Identifiable, Hashable {
let id: UUID
var title: String
static var sampleItems: [Item] {
var items = [Item]()
for i in 0..<10 {
items.append(Item(id: UUID(), title: "item \(i)"))
}
return items
}
}
struct ContentView: View {
@StateObject private var viewModel = ViewModel(with: Item.sampleItems)
var body: some View {
NavigationView {
List {
Section {
ForEach(viewModel.items) { item in
//MARK: Using Array.getBinding(of:) here
NavigationLink(item.title, destination: DetailView(item: viewModel.items.getBinding(of: item)))
}
}
}
}
}
}
struct DetailView: View {
@Binding var item: Item
var body: some View {
TextField("Item Title", text: $item.title)
}
}