我正在寻找一种从详细信息视图编辑列表数据的解决方案。在HomeVC中,我有一个列表,在此列表中,我传递了详细数据和一个用于更新此列表的函数。但这会出错:
class HomeViewModel: ObservableObject {
@Published var vouchers: [Voucher] = []
func fetchVouchers () {
let request = APIEndpoint.getHomeVouchers()
URLSession.shared.dataTask(with: request) { (data, response, err) in
guard let data = data else { return }
let resData = try! JSONDecoder().decode(VouchersResponse.self, from: data)
DispatchQueue.main.async {
self.vouchers = resData.data.promotions
}
}.resume()
}
}
struct HomeVC: View {
@ObservedObject var VM = HomeViewModel()
var body: some View {
List {
ForEach (VM.vouchers) { voucher in
ModalLink (destination: VoucherDetailView(voucher: voucher, didEditVoucher: { v in
self.VM.vouchers.first(where: { $0.id == v.id })?.purchased = true
})) {
VoucherCard(voucher: voucher).frame(width: UIScreen.main.bounds.width - 30, height: (UIScreen.main.bounds.width - 30) * 1)
}.padding(.top, 15)
}
}
}
这是我的详细信息视图,我尝试通过设置purchased
为True
来更新Voucher,然后在List
的{{1}}中更新
HomeVC
错误:
无法分配给属性:函数调用返回不可变的值
代码行:
struct VoucherDetailView: View {
@State var voucher: Voucher
var didEditVoucher: (Voucher) -> ()
var body: some View {
VStack {
Button(action: {
self.voucher.purchased = true
self.didEditVoucher(self.voucher)
})
}
}
}
照片:
答案 0 :(得分:1)
这是因为首先仅是吸气剂:
var first: Element? { get }
不是因为VM或observableObject。
您可以尝试这样:
var id = self.VM.vouchers.first(where: { $0.id == "a" })?.id
getVoucher(by id: id).purchased = true
答案 1 :(得分:0)
针对此问题,我在SwiftUI中找到了针对此数据流的最佳解决方案:
https://swiftwithmajid.com/2019/07/03/managing-data-flow-in-swiftui/
要从详细信息视图编辑列表数据,必须使用struct
映射列表中的索引,然后在此struct
中处理数据
struct IndexedCollection<Base: RandomAccessCollection>: RandomAccessCollection {
typealias Index = Base.Index
typealias Element = (index: Index, element: Base.Element)
let base: Base
var startIndex: Index { base.startIndex }
var endIndex: Index { base.endIndex }
func index(after i: Index) -> Index {
base.index(after: i)
}
func index(before i: Index) -> Index {
base.index(before: i)
}
func index(_ i: Index, offsetBy distance: Int) -> Index {
base.index(i, offsetBy: distance)
}
subscript(position: Index) -> Element {
(index: position, element: base[position])
}
}
extension RandomAccessCollection {
func indexed() -> IndexedCollection<Self> {
IndexedCollection(base: self)
}
}
您无需发布通知或观察键值来指示用户界面中的更改,只需使用SwiftUI提供的正确的Property Wrapper。