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

问题描述 投票:1回答:1

我正在尝试继承或扩展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返回了一个十六进制代码(“ #FFFFFF”)作为类HexColorCode。默认情况下,它将变成String,这样我就必须在要使用它的任何地方使用十六进制初始化UIColor。但是我现在正在尝试使用相同的逻辑,以便自动生成的类实际上具有一个UIColor,可以直接在任何地方使用。但是以上情况发生了。

[我假设Date是public structFoundation,但它有UIColor,即open classUIKit继承自NSObject的自由)。但是,为什么?


我认为可以创建一个“包装”对象,以便我可以说“ HexColorCode”是一个具有单个color字段的独立类,我不得不说myView.backgroundColor = apiModel.color.color而不是仅仅apiModel.color。但是我真的希望它能工作。.

ios swift protocols uicolor
1个回答
1
投票

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

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

class MyColor:UIColor {
    convenience init(myValue: Any) throws {
    self.init(red: 0, green: 0, blue: 0, alpha: 1)
    }
}

编辑:

对不起:尽管此代码可以编译,但缺少该协议。这是(希望)正确的代码:

class MyColor:UIColor, MyProtocol {
    required convenience init(myValue: Any) throws {
    self.init(red: 0, green: 0, blue: 0, alpha: 1)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.