[英]Passing @Binding variable from protocol var to if in SwiftUI
I have a model like this:我有一个像这样的 model:
protocol PurchasableProduct {
var randomId: String { get }
}
class Cart: Identifiable {
var items: [PurchasableProduct]
init(items: [PurchasableProduct]) {
self.items = items
}
}
class Product: Identifiable, PurchasableProduct {
var randomId = UUID().uuidString
var notes: String = ""
}
class DigitalGood: Identifiable, PurchasableProduct {
var randomId = UUID().uuidString
}
where items
conform to protocol PurchasableProduct
.其中
items
符合协议PurchasableProduct
。
I want to build a View that shows cart like this:我想构建一个显示购物车的视图,如下所示:
struct CartView: View {
@State var cart: Cart
var body: some View {
List {
ForEach(cart.items.indices) { index in
CartItemView(item: self.$cart.items[index])
}
}
}
}
where CartItemView
is: CartItemView
在哪里:
struct CartItemView: View {
@Binding var item: PurchasableProduct
var body: some View {
VStack {
if self.item is Product {
Text("Product")
} else {
Text("Digital Good")
}
}
}
}
That's working and give me result as This (screenshot)这是有效的,并给我这个结果(截图)
But I want to extend this a but more that my items
element can be passed as a binding variable lets say as:但我想扩展这个,但更多的是我的
items
元素可以作为绑定变量传递让我们说:
struct CartItemView: View {
@Binding var item: PurchasableProduct
var body: some View {
VStack {
if self.item is Product {
VStack {
TextField("add notes", text: (self.$item as! Product).notes) // ❌ Cannot convert value of type 'String' to expected argument type 'Binding<String>'
TextField("add notes", text: (self.$item as! Binding<Product>).notes) // ⚠️ Cast from 'Binding<PurchasableProduct>' to unrelated type 'Binding<Product>' always fails
}
} else {
Text("Digital Good")
}
}
}
}
What I'm trying to achieve is:我想要实现的是:
CartView
CartView
Not sure if thats syntax issue or my approach issue... how to cast this on body
to get the correct view based on type?不确定那是语法问题还是我的方法问题...如何将其投射到
body
上以根据类型获得正确的视图?
You may create a custom binding:您可以创建自定义绑定:
struct CartItemView: View {
@Binding var item: PurchasableProduct
var product: Binding<Product>? {
guard item is Product else { return nil }
return .init(
get: {
self.$item.wrappedValue as! Product
}, set: {
self.$item.wrappedValue = $0
}
)
}
var body: some View {
VStack {
if product != nil {
TextField("add notes", text: product!.notes)
} else {
Text("Digital Good")
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.