覆盖或扩展UIColor以支持某些协议

时间:2020-01-14 17:42:52

标签: ios swift protocols uicolor

我正在尝试继承或扩展UIColor以支持一些协议。

假设我的协议如下:

public protocol MyProtocol {
    init(myValue: Any) throws
}

由于某种原因,我无法实现它,也不知道为什么。

这适用于所有其他课程:

class MyTestClass:SomeOtherClass, MyProtocol{
    required init(myValue: Any) throws{
        super.init(someOtherClassInitializer:Any)
    }
}

没有问题。但是,如果我尝试使用UIColor进行此操作,则会出错。

class MyColor:UIColor, MyProtocol{

    required init(myValue: Any) throws {
        super.init(red: 0, green: 0, blue: 0, alpha: 1)
    }
}

首先,它抱怨required:Coder-init。很好,提供那个。 fatalError很好。然后它抱怨另一个初始化。它说

'required'初始化程序'init(_colorLiteralRed:green:blue:alpha :)'必须由'UIColor'的子类提供

怪异的弹性,但是还可以。让我们也添加它。我点击“修复”,它添加了这个存根:

@nonobjc required convenience init(_colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {
    fatalError("init(_colorLiteralRed:green:blue:alpha:) has not been implemented")
}

然后它给了我两个错误,一个与我刚刚单击“修复”的错误相同(这又添加了另一个相同的init,一次又一次),另一个错误提示:

不支持从扩展名覆盖非@objc声明

我不在扩展程序中,但我认为此便捷初始化程序可能是?但是为什么我需要实施-而且也无法实施


我知道,“您不应该继承UIColor”,但是我想必须这样做。 这是一个奇怪的请求,因此提供了一些背景信息。我正在使用Apollo库执行GraphQL网络任务,该任务使用脚本将预期的响应转换为强类型的swift对象,因此我可以在代码中使用它们而无需手动反序列化它们。运行正常。

大多数值是标准和原始类型,例如String,Int等,但是有时服务器会尝试向我发送Swift外部类的对象,而这些对象默认为String。很好。但我想要更多幻想。例;服务器可能会以名为DateTime的类的形式返回值“ 2020-01-14T10:00:00”,但是由于“ DateTime”在我的项目或Swift中不存在,因此自动生成的类将它们包含为String值,我将不得不将其视为字符串。

由于我想一直使用这些自动生成的类直到视图,因此这意味着我必须在使用该类的所有位置将其从String转换为Date。另一种选择是创建我自己的所有类的版本,并将所有外部类转换为我自己的类,例如String-> Date,这很无聊。我要为我自动完成此操作。

好消息是-Apollo允许我创建自己的Custom Scalars。因此,以这个“ DateTime-> Date”为例,我可以简单地说

typealias DateTime = Date
extension DateTime, JSONDecodable, JSONEncodable{ ... }

这使Apollo知道存在一个相应的类,可以将“ DateTime”类的对象转换为该类。协议JSONDecodable和JSONEncodable告诉它如何(我自己实现)。 使用此功能,将自动生成的代码生成,因此任何日期值现在都是DateTime(例如Date),而不是String。很好!

所以我想,为什么不利用这个优势呢?我们还从该API接收十六进制颜色。因此,我们做到了这一点,因此API返回了HexColorCode类的十六进制代码(“ #FFFFFF”)。 默认情况下,这将变成String,因此我必须在要使用它的所有位置使用十六进制初始化UIColor。但是我现在正尝试使用相同的逻辑,以便自动生成的类实际上具有一个UIColor,可以直接在任何地方使用。但是以上情况确实发生了。

我假设Date(来自public struct的{​​{1}}具有一定的自由度,UIColor(来自Foundation的{​​{1}}的{​​{1}})没有没有。但是,为什么?


我认为可以创建一个“包装器”对象,这样我可以说“ HexColorCode”是一个具有单个open class字段的独立类,我不得不说{{1 }},而不只是UIKit。但是我真的希望它能工作。.

1 个答案:

答案 0 :(得分:1)

我检查了您的情况,并给人留下了编译器感到困惑的印象。
但是可能有解决方案。以下代码为我编译时没有问题:

Post = models.ForeignKey(...)

编辑:

很抱歉:尽管此代码可以编译,但缺少协议。
这是(希望)正确的代码:

form.instance.post = get_object_or_404(...)