Как использовать UIColor как RawValue типа enum в Swift

Я пытался объявить тип перечисления, используя UIColor в качестве необработанного значения. Вот код:

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)
}

Но я получил две ошибки в первой строке:

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

Хотите добавить заглушки протокола? Почини это

Raw type 'UIColor' is not expressible by any literal

Если я воспользовался первым советом, Xcode добавит typealias RawValue = <#type#> в начале внутри скобок. Но я не уверен, что с этим делать. И если бы я обратился ко второй ошибке, как мне изменить тип raw на литерал?

1 ответ

Решение

Немного покопавшись, я обнаружил пост Оле Бегеманна, в котором упоминается, как создать настраиваемую коллекцию перечисления цветов, которая SGColor в этом вопросе соответствует протоколу RawRepresentable.

По сути, хотя XCode умно предлагает мне исправить проблему, явно указав ей необработанный тип (как видно из первой ошибки в вопросе), он все еще недостаточно умен, чтобы понять, как это сделать для цветных литералов, или UIColor.

Уле Бегеманн упомянул, что ручное соответствие исправит это. И он дал подробное объяснение того, как это сделать.

Пока он использовал UIColor цветные объекты (такие как UIColor.red), Я попробовал и протестировал целесообразность использования цветовых литералов, поскольку в целом они более визуально прямые и более настраиваемые.

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)
        }
    }
}
Другие вопросы по тегам