Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use UIColor as RawValue of an enum type in Swift

I was trying to declare an enum type using UIColor as the raw value. Here is the code:

enum SGColor: UIColor {
    case red = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
    case green = #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
    case purple = #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
}

But I got two errors in the first line:

'SGColor' declares raw type 'UIColor', but does not conform to
RawRepresentable and conformance could not be synthesized

Do you want to add protocol stubs? Fix it

Raw type 'UIColor' is not expressible by any literal

If I took the first advice, Xcode will add typealias RawValue = <#type#> at the beginning inside of the parentheses. But I am not sure what to do with it. And if I were to address the second error, how do I change the raw type to a literal?

like image 511
jackxujh Avatar asked Mar 09 '18 10:03

jackxujh


People also ask

What is Rawvalue in enum?

Enum raw values To set a value to your enum, you need to assign a data type to it. In our case above, we are using a type of String . Each raw value for our enum case must be a unique string, character, or value of any integer or floating-point type. This means the value for the two case statements cannot be the same.

Can enum inherit from another enum Swift?

As Korpel answered already, currently there is no actual inheritance supported for Enums. So it is not possible to have a certain Enum extend and inherit the cases of another enum.

Can we define method in enum Swift?

In Swift, you can set data types and values ​​in Enums and define methods or properties on them. Also, using Codable, it is possible to convert from value to Constant very easily. So, Code that uses Enums can be more elegantly organized.

Can enum adopt protocol Swift?

Yes, enums can conform protocols. You can use Swift's own protocols or custom protocols. By using protocols with Enums you can add more capabilities.


1 Answers

After some digging, I found a post by Ole Begemann that mentions how to make a customized color enumeration collection, which is SGColor in this question, conform to the RawRepresentable protocol.

Basically, while Xcode is smart to suggest me to fix the problem by explicitly telling it the raw type (as seen in the first error in the question), it is still not intelligent enough to figure out how to do that for color literals, or UIColor.

Ole Begemann mentioned a manual conformance will fix this. And he gave a detailed explanation as of how to do it.

While he used UIColor color objects (such as UIColor.red), I tried and tested the feasibility of using color literals, since in general, they are more visually direct and more customizable.

enum SGColor {
    case red
    case green
    case purple
}
extension SGColor: RawRepresentable {
    typealias RawValue = UIColor

    init?(rawValue: RawValue) {
        switch rawValue {
        case #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1): self = .red
        case #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1): self = .green
        case #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1): self = .purple
        default: return nil
        }
    }

var rawValue: RawValue {
        switch self {
        case .red: return #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        case .green: return #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
        case .purple: return #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
        }
    }
}
like image 188
jackxujh Avatar answered Sep 28 '22 01:09

jackxujh