覆盖或扩展 UIColor 以支持某些协议
Overriding or extending UIColor to support certain protocols
我正在尝试子class 或扩展 UIColor 以支持一些协议。
假设我的协议如下所示:
public protocol MyProtocol {
init(myValue: Any) throws
}
由于某些原因,我无法实现它,我也不知道为什么。
这适用于所有其他 classes:
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。好的,提供那个。致命错误很好。然后它抱怨另一个初始化。它说
'required' initializer 'init(_colorLiteralRed:green:blue:alpha:)' must be provided by subclass of 'UIColor'
奇怪的弯曲,但还好。让我们也补充一下。我单击 "Fix",它添加了这个存根:
@nonobjc required convenience init(_colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {
fatalError("init(_colorLiteralRed:green:blue:alpha:) has not been implemented")
}
然后它给了我两个错误,一个与我刚刚单击 "Fix" 的错误相同(它添加了另一个相同的初始化,并且一次又一次),另一个是:
Overriding non-@objc declarations from extensions is not supported
我没有在扩展中,但我想这个便利初始化程序可能是?但是为什么需要我实现——而且又不可能实现?
我知道,"you shouldn't subclass UIColor",但我想如果我想让它起作用,我必须这样做。
这是一个奇怪的请求,所以一些背景信息;我正在使用 Apollo 库执行 GraphQL 网络任务,它使用脚本将预期响应转换为强类型 swift 对象,这样我就可以在代码中使用它们而无需手动反序列化它们。它运行良好。
大多数值都是标准和原始类型,如 String、Int 等,但有时服务器会尝试向我发送一个 class 的对象,这对 Swift 来说是陌生的,并且这些将默认为 String
。这很好。但我想要更花哨的。例子;值“2020-01-14T10:00:00”可能会作为名为 DateTime
的 class 从服务器返回,但由于 "DateTime" 在我的项目或 Swift,自动生成的 classes 会将它们作为 String
值包含,我必须将其视为字符串。
因为我想一直使用这些自动生成的 classes 直到视图,这意味着我必须在任何使用它的地方将它从 String 转换为 Date。另一种选择是创建我自己的所有 classes 版本,并将所有外国 classes 转换为我自己的版本,例如 String->Date,这很无聊。我希望它自动为我完成。
好处是 - Apollo 允许我创建自己的自定义标量。所以对于这个 "DateTime -> Date"-example,我可以简单地说
typealias DateTime = Date
extension DateTime, JSONDecodable, JSONEncodable{ ... }
这让 Apollo 知道有一个对应的 class 可以将 class "DateTime" 的对象转换成。协议 JSONDecodable 和 JSONEncodable 告诉它如何(我自己实现)。
使用它,将生成自动生成的代码,以便任何日期值现在都是日期时间(例如日期)而不是字符串。不错!
所以我想,为什么不利用这个优势呢?我们还从这个 API 收到十六进制颜色。所以我们已经做到了 API returns 十六进制代码(“#FFFFFF”)作为 class HexColorCode
。
默认情况下,这只会变成一个 String
,所以我必须在任何我想使用它的地方用十六进制初始化一个 UIColor 。但我现在正尝试使用相同的逻辑,以便自动生成的 classes 实际上有一个我可以在任何地方直接使用的 UIColor。但是发生了以上情况。
我假设 Date,作为 Foundation
的 public struct
,具有一些自由度,而 UIColor,从 UIKit
继承自 NSObject
的 open class
,没有。但是什么以及为什么?
我认为可以创建一个 "wrapper"-object,所以我可以说 "HexColorCode" 是一个独立的 class,它有一个 color
-field,我不得不说 myView.backgroundColor = apiModel.color.color
而不是 apiModel.color
。但我真的希望它能起作用..
我检查了你的情况,我也有编译器混淆的印象。
但可能有解决办法。以下代码为我编译没有问题:
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)
}
}
我正在尝试子class 或扩展 UIColor 以支持一些协议。
假设我的协议如下所示:
public protocol MyProtocol {
init(myValue: Any) throws
}
由于某些原因,我无法实现它,我也不知道为什么。
这适用于所有其他 classes:
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。好的,提供那个。致命错误很好。然后它抱怨另一个初始化。它说
'required' initializer 'init(_colorLiteralRed:green:blue:alpha:)' must be provided by subclass of 'UIColor'
奇怪的弯曲,但还好。让我们也补充一下。我单击 "Fix",它添加了这个存根:
@nonobjc required convenience init(_colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {
fatalError("init(_colorLiteralRed:green:blue:alpha:) has not been implemented")
}
然后它给了我两个错误,一个与我刚刚单击 "Fix" 的错误相同(它添加了另一个相同的初始化,并且一次又一次),另一个是:
Overriding non-@objc declarations from extensions is not supported
我没有在扩展中,但我想这个便利初始化程序可能是?但是为什么需要我实现——而且又不可能实现?
我知道,"you shouldn't subclass UIColor",但我想如果我想让它起作用,我必须这样做。 这是一个奇怪的请求,所以一些背景信息;我正在使用 Apollo 库执行 GraphQL 网络任务,它使用脚本将预期响应转换为强类型 swift 对象,这样我就可以在代码中使用它们而无需手动反序列化它们。它运行良好。
大多数值都是标准和原始类型,如 String、Int 等,但有时服务器会尝试向我发送一个 class 的对象,这对 Swift 来说是陌生的,并且这些将默认为 String
。这很好。但我想要更花哨的。例子;值“2020-01-14T10:00:00”可能会作为名为 DateTime
的 class 从服务器返回,但由于 "DateTime" 在我的项目或 Swift,自动生成的 classes 会将它们作为 String
值包含,我必须将其视为字符串。
因为我想一直使用这些自动生成的 classes 直到视图,这意味着我必须在任何使用它的地方将它从 String 转换为 Date。另一种选择是创建我自己的所有 classes 版本,并将所有外国 classes 转换为我自己的版本,例如 String->Date,这很无聊。我希望它自动为我完成。
好处是 - Apollo 允许我创建自己的自定义标量。所以对于这个 "DateTime -> Date"-example,我可以简单地说
typealias DateTime = Date
extension DateTime, JSONDecodable, JSONEncodable{ ... }
这让 Apollo 知道有一个对应的 class 可以将 class "DateTime" 的对象转换成。协议 JSONDecodable 和 JSONEncodable 告诉它如何(我自己实现)。 使用它,将生成自动生成的代码,以便任何日期值现在都是日期时间(例如日期)而不是字符串。不错!
所以我想,为什么不利用这个优势呢?我们还从这个 API 收到十六进制颜色。所以我们已经做到了 API returns 十六进制代码(“#FFFFFF”)作为 class HexColorCode
。
默认情况下,这只会变成一个 String
,所以我必须在任何我想使用它的地方用十六进制初始化一个 UIColor 。但我现在正尝试使用相同的逻辑,以便自动生成的 classes 实际上有一个我可以在任何地方直接使用的 UIColor。但是发生了以上情况。
我假设 Date,作为 Foundation
的 public struct
,具有一些自由度,而 UIColor,从 UIKit
继承自 NSObject
的 open class
,没有。但是什么以及为什么?
我认为可以创建一个 "wrapper"-object,所以我可以说 "HexColorCode" 是一个独立的 class,它有一个 color
-field,我不得不说 myView.backgroundColor = apiModel.color.color
而不是 apiModel.color
。但我真的希望它能起作用..
我检查了你的情况,我也有编译器混淆的印象。
但可能有解决办法。以下代码为我编译没有问题:
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)
}
}