Given this Struct who conforms to Relationable protocol
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 }
}
And this Published variable in a ViewModel who conforms to ObservableObject
class RelationsViewModel: ObservableObject {
@Published var selectedRelation: any Relationable = PersonalRelation()
}
the relationship variable is a Enum who conforms to CaseIterable and Hashable
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
}
}
}
If I got 3 structs who conforms to the protocol with each one this variable (relationship), I want to assign it to the Picker selection instead of making 3 Picker
when assigning a known type(String) from the protocol its working
TextField("Nickname", text: $relationsVM.selectedRelation.nickname)
.modifier(TextFieldModifier(width: 250, height: 30))
.padding(.top)
BUT, with the picker it wont work
Picker("Type", selection: $relationsVM.selectedRelation.relationship) {
//ForEach got a simple string array
ForEach(relationsVM.allRelationships) { relationType in
Text(relationType)
}
}.pickerStyle(.menu)
The compiler is unable to type check and compile I know it is because of the selected parameter of the picker, maybe need to force cast the type somewhere?
selection, not the published value itself. Another issue I can imagine is thatRelationableis a protocol, so the compiler can't be sure it is going to be a value type, which is required for a binding.RelationsViewModel(or add and additional view model), and have a published property ofRomanticRelationType, which is a value type and perfect for aPicker.String, which is a value type.Relationshipis anassociatedtypeand not a value type (could be a class or other reference type).rawValue(anIntfor example), and your view model contain a published property of anInt. You would additionally need another published property to know which one of the enums is the current one.