我正在尝试使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
而不包装它的建议,都受到高度赞赏。
答案 0 :(得分:1)
我正在写手机,所以我无法尝试此代码段,但我认为这可以工作。让我知道是否有帮助。
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)
}
}