SwifUI:无法将类型'Binding <Veggies>-> VeggiesView'的值转换为预期的参数类型'__-> _'

问题描述

     class VeggieProperties: Identifiable,ObservableObject 
            {
                //id implementation
                @Published var name: String = ""
                  //inits with random properties for testing purposes
            }
    
           class Veggies: Identifiable,ObservableObject 
        {
            //id implementation
            @Published var name: String = ""
            @Published var properties: [VeggiesProperties] = [VeggiesProperties]
            //inits with random names for testing purposes
        }

    class VeggiesToBuy: Identifiable,ObservableObject
    {
    @Published var name: String = ""
    @Published var veggiesList: [Veggies] = [Veggies]()
    //inits to populate veggiesList with random Veggies for testing purposes
    }

    struct GenericView<Elements,Content>: View where Elements: RandomAccessCollection,Elements.Element: Hashable,Content: View 
{
        var data: Elements
        var content: (Elements.Element) -> Content
        var body: some View {
                   vstack {
                    ForEach(data,id: \.self) { self.content($0)}
            }
        }
    }


struct VeggiesView: View {
    @Binding var veggie: Veggies
    var body: some View {
        vstack {
            Text("\(veggie.name)")
            GenericView(data: veggies.properties) {
                property in
                Text("\(property.name)")
            }
        }
    }
}

错误出现在这里

struct VeggiesToBuy: View {
   @Binding var veggiesToBuyList: [Veggies]

    var body: some View {
        HStack{
***//            GenericView(data: veggiesToBuyList) { veggies in VeggiesView(veggie: veggies)} <- also doesn't work
            ForEach(self.veggiesToBuyList,id: \.self) {veggies in VeggiesView(veggie: veggies)}***
        }
    }
}

从这里的类似问题来看,似乎编译器可能没有指向导致错误的确切字符串。就我而言,它指向: ForEach(self.veggiesToBuyList,id:.self){VeggiesView中的蔬菜(veggie:veggies)} 或另一个带有GenericView的实现。有什么想法可以使它起作用,为什么会弹出此错误

解决方法

您的模型使用引用类型的可观察对象,因此与@ObservedObject结合使用而不是与绑定结合使用

这里是完整的固定代码。经过Xcode 12测试。

class VeggieProperties: Identifiable,ObservableObject,Hashable
{
    static func == (lhs: VeggieProperties,rhs: VeggieProperties) -> Bool {
        lhs === rhs  // << for simplicity,do as you need
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
    }

    //id implementation
    @Published var name: String = ""
    //inits with random properties for testing purposes
}

class Veggies: Identifiable,Hashable
{
    static func == (lhs: Veggies,rhs: Veggies) -> Bool {
        lhs === rhs  // << for simplicity,do as you need
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
        hasher.combine(properties)
    }

    //id implementation
    @Published var name: String = ""
    @Published var properties: [VeggieProperties] = [VeggieProperties]()
    //inits with random names for testing purposes
}

class VeggiesToBuy: Identifiable,ObservableObject
{
    @Published var name: String = ""
    @Published var veggiesList: [Veggies] = [Veggies]()
    //inits to populate veggiesList with random Veggies for testing purposes
}

struct GenericView<Elements,Content>: View where Elements: RandomAccessCollection,Elements.Element: Hashable,Content: View
{
    var data: Elements
    var content: (Elements.Element) -> Content
    var body: some View {
        VStack {
            ForEach(data,id: \.self) { self.content($0)}
        }
    }
}


struct VeggiesView: View {
    @ObservedObject var veggie: Veggies
    var body: some View {
        VStack {
            Text("\(veggie.name)")
            GenericView(data: veggie.properties) {
                property in
                Text("\(property.name)")
            }
        }
    }
}

struct VeggiesToBuyView: View {
    var veggiesToBuyList: [Veggies]

    var body: some View {
        HStack{
            GenericView(data: veggiesToBuyList) { veggies in
                VeggiesView(veggie: veggies)
            }
        }
    }
}