gpt4 book ai didi

SwiftUI:扩展数组以获得数组实例的绑定(bind)

转载 作者:行者123 更新时间:2023-12-04 03:35:08 24 4
gpt4 key购买 nike

我想延长 Array<T>基本上返回 Binding<T> .这样做的目的是有一种方便的方法来创建 BindingDetailView这是从 NavigationLink 调用的的 List .

这是我到目前为止得到的:

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
}
}
}

我收到错误 Escaping closure captures mutating 'self' parameter在指定地点。我该如何解决这个问题?

长话短说

以下是我想使用此扩展程序的方式:

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)
}
}

最佳答案

将扩展名更改为:

extension Binding {
func getBinding<T>(of instance: T) -> Binding<T>
where Value == [T], T: Identifiable {
if let index = self.wrappedValue.firstIndex(where: { $0.id == instance.id }) {
return .init(
get: { self.wrappedValue[index] }, //error
set: { self.wrappedValue[index] = $0 }) //error
} else {
fatalError() //implement error handling here
}
}
}

现在代替 DetailView(item: viewModel.items.getBinding(of: item))DetailView(item: $viewModel.items.getBinding(of: item)) (注意 $)

编辑,奖励:

我有一份奖励送给你,希望你会喜欢。这将使过程更好,代码更清晰。请注意,它与您当前的代码在性能方面的差异为 0。
添加此扩展以开始:

extension Binding {
subscript<T>(_ index: Int) -> Binding<T> where Value == [T] {
.init(get: {
self.wrappedValue[index]
},
set: {
self.wrappedValue[index] = $0
})
}
}

并将您的 ForEach 更改为:

ForEach(viewModel.items.indices) { index in
let item = viewModel.items[index]
NavigationLink(item.title, destination: DetailView(item: $viewModel.items[index]))
}

希望你喜欢:)

关于SwiftUI:扩展数组以获得数组实例的绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67059931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com