IB Designables:无法呈现和更新自动布局状态...代理崩溃
IB Designables: Failed to render and update auto layout status ...The agent crashed
当我在 IBDesignable 中包含以下代码时,界面生成器代理崩溃 class。
self.backgroundColor = UIColor.mooButtonBackgroundColor
颜色的表示形式为:
@nonobjc class var mooButtonBackgroundColor : UIColor {
UIColor(named: "Color.Button.Background")! // 0.129, 0.490, 0.851, 1
}
但是,如果我将返回的值更改为:
@nonobjc class var mooButtonBackgroundColor : UIColor {
.green //UIColor(named: "Color.Button.Background")! // 0.129, 0.490, 0.851, 1
}
一切正常。
我也试过没有@nonobjc标签的方法,结果一样。
IBDesigner 中是否存在阻止使用命名颜色的限制?
有人可以建议一种方法来解决 IBDesigner 中的崩溃问题吗?
你问过:
Can someone suggest a method to overcome this crash in IBDesigner?
我们无法解决命名颜色问题,但我们肯定可以通过避免强制展开运算符来消除崩溃,!
。例如。您可以改用 nil
-合并运算符 ??
,这样您就有了一些 IB 的后备颜色,例如
backgroundColor = UIColor(named: "Color.Button.Background") ?? .blue
但是,如果你不强制解包,它就不会崩溃。虽然它不会在 IB 中使用您命名的颜色,但它会在您 运行 应用程序时使用。
就个人而言,我会避免在可设计视图本身中设置通常在 IB 中设置的任何属性(例如 backgroundColor
)。我认为在 IB 中查看某些视图,更改 属性,例如背景颜色,但没有正确呈现它是非常令人困惑的。
可以在 IB 中配置的内容应该保留在 IB 中以避免混淆。
但是让我们考虑一个例子,我确实希望自定义颜色 属性 使用命名颜色。我会声明一个 @IBInspectable
颜色 属性,例如,考虑这个带有自定义 fillColor
:
的圆形视图
@IBDesignable
class CircleView: UIView {
let shapeLayer = CAShapeLayer()
@IBInspectable var fillColor: UIColor = .blue { didSet { shapeLayer.fillColor = fillColor.cgColor } }
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
override func layoutSubviews() {
super.layoutSubviews()
updatePaths()
}
}
private extension CircleView {
func configure() {
layer.addSublayer(shapeLayer)
shapeLayer.fillColor = fillColor.cgColor
}
func updatePaths() {
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = min(bounds.width, bounds.height) / 2
shapeLayer.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath
}
}
然后我会在 IB 属性检查器中设置命名颜色:
另一种方法是不在资产目录中使用命名颜色,而是定义您自己的 UIColor
扩展名:
extension UIColor {
static let buttonBackground = #colorLiteral(red: 0, green: 1, blue: 1, alpha: 1)
}
然后当你想设置一些颜色时属性,你可以这样做:
backgroundColor = .buttonBackground
这种方法的缺点是您无法将 IB 中的命名颜色用于其他控件。但这是另一种需要考虑的模式。
好的,事实证明这是一个错误。已在 Xcode 11.4 中修复:
Fixed a bug where using named colors in IBInspectable properties would use a fixed color at runtime, instead of the dynamic color from the asset catalog. (55248109) (FB7248211)
当我在 IBDesignable 中包含以下代码时,界面生成器代理崩溃 class。
self.backgroundColor = UIColor.mooButtonBackgroundColor
颜色的表示形式为:
@nonobjc class var mooButtonBackgroundColor : UIColor {
UIColor(named: "Color.Button.Background")! // 0.129, 0.490, 0.851, 1
}
但是,如果我将返回的值更改为:
@nonobjc class var mooButtonBackgroundColor : UIColor {
.green //UIColor(named: "Color.Button.Background")! // 0.129, 0.490, 0.851, 1
}
一切正常。
我也试过没有@nonobjc标签的方法,结果一样。
IBDesigner 中是否存在阻止使用命名颜色的限制?
有人可以建议一种方法来解决 IBDesigner 中的崩溃问题吗?
你问过:
Can someone suggest a method to overcome this crash in IBDesigner?
我们无法解决命名颜色问题,但我们肯定可以通过避免强制展开运算符来消除崩溃,!
。例如。您可以改用 nil
-合并运算符 ??
,这样您就有了一些 IB 的后备颜色,例如
backgroundColor = UIColor(named: "Color.Button.Background") ?? .blue
但是,如果你不强制解包,它就不会崩溃。虽然它不会在 IB 中使用您命名的颜色,但它会在您 运行 应用程序时使用。
就个人而言,我会避免在可设计视图本身中设置通常在 IB 中设置的任何属性(例如 backgroundColor
)。我认为在 IB 中查看某些视图,更改 属性,例如背景颜色,但没有正确呈现它是非常令人困惑的。
可以在 IB 中配置的内容应该保留在 IB 中以避免混淆。
但是让我们考虑一个例子,我确实希望自定义颜色 属性 使用命名颜色。我会声明一个 @IBInspectable
颜色 属性,例如,考虑这个带有自定义 fillColor
:
@IBDesignable
class CircleView: UIView {
let shapeLayer = CAShapeLayer()
@IBInspectable var fillColor: UIColor = .blue { didSet { shapeLayer.fillColor = fillColor.cgColor } }
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
override func layoutSubviews() {
super.layoutSubviews()
updatePaths()
}
}
private extension CircleView {
func configure() {
layer.addSublayer(shapeLayer)
shapeLayer.fillColor = fillColor.cgColor
}
func updatePaths() {
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = min(bounds.width, bounds.height) / 2
shapeLayer.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath
}
}
然后我会在 IB 属性检查器中设置命名颜色:
另一种方法是不在资产目录中使用命名颜色,而是定义您自己的 UIColor
扩展名:
extension UIColor {
static let buttonBackground = #colorLiteral(red: 0, green: 1, blue: 1, alpha: 1)
}
然后当你想设置一些颜色时属性,你可以这样做:
backgroundColor = .buttonBackground
这种方法的缺点是您无法将 IB 中的命名颜色用于其他控件。但这是另一种需要考虑的模式。
好的,事实证明这是一个错误。已在 Xcode 11.4 中修复:
Fixed a bug where using named colors in IBInspectable properties would use a fixed color at runtime, instead of the dynamic color from the asset catalog. (55248109) (FB7248211)