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

vsikbqxv  于 2023-01-25  发布在  Swift
关注(0)|答案(2)|浏览(132)

我正在尝试子类化或扩展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是好的。然后它抱怨另一个init。它说
“必需的”初始值设定项“init(_colorLiteralRed:绿色:blue:alpha:)”必须由“UIColor”的子类提供
很奇怪的flex,但是没关系。让我们添加它。我点击“修复”,它添加了这个存根:

@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。这是非常好的。但是我想要更花哨一些。例如;值“2020-01- 14 T10:00:00”可能作为一个名为DateTime的类从服务器返回,但由于“DateTime”在我的项目或Swift中不存在,因此自动生成的类将它们作为一个String值包含,我将不得不将其视为一个String。
因为我想使用这些自动生成的类,一直到视图,这意味着我必须在所有使用它的地方把它从String转换成Date。另一个选择是创建我自己的所有类的版本,并把所有外来的类转换成我自己的,像String-〉Date,这很无聊。我想自动为我完成这件事。
好的方面是- Apollo允许我创建自己的自定义标量。因此,对于这个“DateTime -〉Date”示例,我可以简单地说

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

这让Apollo知道有一个对应的类,类“DateTime”的对象可以转换成这个类。JSONDecodable和JSONEncodable协议告诉它如何转换(我自己实现了)。使用这个协议,自动生成的代码将生成,这样任何日期值现在都是DateTime(例如Date)而不是String。不错!
所以我想,为什么不利用这个优势呢?我们也从这个API接收十六进制颜色。所以我们让它返回一个十六进制代码(“#FFFFFF”)作为类HexColorCode。默认情况下,这只会变成一个String,这样我就必须在任何地方用十六进制初始化一个UIColor。我现在尝试使用相同的逻辑,以便自动生成的类实际上有一个UIColor,我可以在任何地方直接使用它。
我假设Date是从Foundation继承而来的public struct,它具有UIColor(从UIKit继承而来的open class,继承自NSObject)所没有的一些自由。
我认为可以创建一个“ Package 器”对象,这样我就可以说“HexColorCode”是一个独立的类,它有一个color字段,我必须说myView.backgroundColor = apiModel.color.color而不仅仅是apiModel.color

2o7dmzc5

2o7dmzc51#

我检查了你的情况,我也有编译器混淆的印象。
但是可能有一个解决方案。下面的代码为我编译没有问题:

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

c3frrgcw2#

如果你确实需要子类化UIColor,使用Objective-C来实现。这将绕过Swift中的颜色常量初始化器。

相关问题