具有协议类型的 Swiftui 选取器 - 编译器无法对此表达式进行类型检查

Swiftui Picker with protocol type - Compiler is unable to type-check this expression

提问人:David.C 提问时间:3/10/2023 最后编辑:David.C 更新时间:3/22/2023 访问量:156

问:

鉴于这个符合协议的结构Relationable

struct RomanticRelation: Relationable{
    
    typealias Relationship = RomanticRelationType
    typealias Relation = RomanticRelation
    var nickname: String
    var lastInteracted: Date
    var relationship: RomanticRelationType = .couple //Enum type

}

protocol Relationable {
    
    associatedtype Relation
    associatedtype Relationship:Hashable  //Enum
    var nickname:String { get set }
    var lastInteracted:Date { get set }
    var relationship:Relationship { get set }
    var typicalInterests:[String] { get }
    var interests:[String] { get set }
    
}

而这个变量在符合PublishedObservableObject

class RelationsViewModel: ObservableObject {
    
    @Published var selectedRelation: any Relationable = PersonalRelation()

}

变量是符合 和relationshipEnumCaseIterableHashable


enum RomanticRelationType:Hashable, CaseIterable {
   

    case couple, married, engaged
    
    var title: String {
        
        switch self {
        case .couple:
            return "Couple"
        case .married:
            return "Married"
        case .engaged:
            return "Engaged"
        }
    }
    var priority: Int {
        switch self {
        case .couple:
            return 3
        case .engaged:
            return 2
        case .married:
            return 1
        }
    }
    
}

如果我有 3 个结构体符合协议,每个结构体都有这个变量(关系),我想将其分配给选择而不是制作 3 个PickerPicker

从协议中分配已知类型(String)时,其工作

 TextField("Nickname", text: $relationsVM.selectedRelation.nickname)
                                .modifier(TextFieldModifier(width: 250, height: 30))
                                .padding(.top)

但是,使用选择器,它将不起作用

Picker("Type", selection: $relationsVM.selectedRelation.relationship) {
    //ForEach got a simple string array
ForEach(relationsVM.allRelationships) { relationType in 
Text(relationType)
   }
  }.pickerStyle(.menu)

编译器无法进行类型检查和编译,我知道这是因为选择器的参数,也许需要在某处强制转换类型?selected

swiftui swift-protocols swiftui-picker

评论

0赞 Vicente Garcia 3/16/2023
在我看来,问题可能是您将已发布值的属性分配给 ,而不是已发布值本身。我能想象到的另一个问题是,这是一个协议,所以编译器不能确定它是否会是一个值类型,这是绑定所必需的。selectionRelationable
0赞 Vicente Garcia 3/16/2023
我会重构您的(或添加和附加视图模型),并具有 的已发布属性,这是一个值类型,非常适合 .RelationsViewModelRomanticRelationTypePicker
0赞 David.C 3/16/2023
每个结构有 3 种类型的枚举,这就是为什么我在各自的结构中声明每个属性的原因。我不想将其声明为独立。每个枚举需要 3 个属性。另外,为什么它适用于昵称属性,而不适用于关系属性?@vicegax
0赞 Vicente Garcia 3/16/2023
昵称是 type ,这是一个值类型。 是值类型,而不是值类型(可以是类或其他引用类型)。StringRelationshipassociatedtype
0赞 Vicente Garcia 3/16/2023
每个枚举 1 个已发布的属性可能是一种方法;另一种选择是使所有枚举都具有 (例如,),并且视图模型包含 .您还需要另一个已发布的属性来了解哪个枚举是当前枚举。rawValueIntInt

答: 暂无答案