我正在努力使 UIFont
符合 Decodable
,但我遇到了困难。
我目前的解决方案是将 UIFont 包装在这样的 Font 结构中
public struct Font: Decodable{
let font: UIFont
private enum CodingKeys: String, CodingKey {
case size
case font
}
public init(from decoder: Decoder){
do{
let values = try decoder.container(keyedBy: CodingKeys.self)
font = UIFont(name: try values.decode(String.self, forKey: .font), size: try values.decode(CGFloat.self, forKey: .size))!
} catch{
fatalError("Font configuration error:\(error)")
}
}
}
这行得通,但我看起来很笨拙,所以我改为这样尝试:
final class Font: UIFont, Decodable{
private enum CodingKeys: String, CodingKey {
case size
case font
}
convenience init(from decoder: Decoder) {
do{
let values = try decoder.container(keyedBy: CodingKeys.self)
super.init(name: try values.decode(String.self, forKey: .font), size: try values.decode(CGFloat.self, forKey: .size))
} catch{
fatalError("Font configuration error:\(error)")
}
}
}
但是这不起作用,因为 init(from decoder: Decoder)
不能是一个失败的初始化器,而 UIFont.init(name: String, size: CGFloat)
是一个可失败的初始化器,并且不可能从一个不可失败的初始化器调用一个可失败的初始化器。
对于如何使 UIFont
符合 Decodable
而无需包装的任何建议,我们将不胜感激。
最佳答案
我正在用手机写作,所以我不能尝试这个片段,但我认为它可以工作。让我知道是否有帮助。
final class Font: Codable {
let size: CGFloat
let name: String
var font: UIFont = UIFont.init()
init(s: CGFloat, n: String) {
size = s
name = n
font = UIFont(name: name, size: size) ?? UIFont.systemFont(ofSize: size)
}
enum CodingKeys: String, CodingKey {
case size
case name
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
size = try container.decode(CGFloat.self, forKey: .size)
name = try container.decode(String.self, forKey: .name)
font = UIFont(name: name, size: size) ?? UIFont.systemFont(ofSize: size)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(size, forKey: .size)
try container.encode(name, forKey: .name)
}
}
关于ios - 如何使 UIFont 符合 decodable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56361762/