0

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?

17
  • Seems to me the problem might be that you are assigning a property of a published value to the selection, not the published value itself. Another issue I can imagine is that Relationable is a protocol, so the compiler can't be sure it is going to be a value type, which is required for a binding. Commented Mar 16, 2023 at 10:42
  • I would refactor your RelationsViewModel (or add and additional view model), and have a published property of RomanticRelationType, which is a value type and perfect for a Picker. Commented Mar 16, 2023 at 10:44
  • there is 3 type of enums for each struct, that's why I declared each property in their respective struct. I don't want to declare it as a standalone. I would need 3 property for each enum. also why its working for the nickname property but not with the relationship property? @vicegax Commented Mar 16, 2023 at 10:48
  • nickname is type String, which is a value type. Relationship is an associatedtype and not a value type (could be a class or other reference type). Commented Mar 16, 2023 at 10:56
  • 1 published property for each enum could be a way to go; another option could be making all your enums have a rawValue (an Int for example), and your view model contain a published property of an Int. You would additionally need another published property to know which one of the enums is the current one. Commented Mar 16, 2023 at 10:59

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.