@IBDesignable 视图不会在 Interface Builder 中绘制背景颜色
@IBDesignable view doesn't draw background color inside Interface Builder
我很好奇为什么不将 backgroundColor
设置为红色?
@IBDesignable class CustomLabel: UIView {
let view = UIView()
func setup() {
backgroundColor = UIColor.red
view.backgroundColor = UIColor.green
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
addSubview(view)
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
}
这是结果。
这就是我期望的样子。
在 Interface builder(IB) 中呈现时,在调用 init
后加载自定义 UI 元素的 IB 中设置的属性。正在调用您在 init
中设置 backgroundColor
的代码。但在那之后,它再次为 IB.
中的 backgroundColor
的值设置 backgroundColor
我找不到这方面的 Apple 文档。我这样说是基于以下分析。为了调试,我稍微修改了你的代码。
@IBDesignable class CustomLabel: UIView {
let view = UIView()
override var backgroundColor: UIColor? {
didSet {
print("here: "); // break point 1
}
}
func setup() {
self.backgroundColor = UIColor.redColor() // break point 2
view.backgroundColor = UIColor.greenColor()
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
addSubview(view)
}
override init(frame: CGRect) {
super.init(frame: frame) // break point 3
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) // break point 4
setup()
}
}
现在,将断点放在所有方法中。然后,在 Interface Builder 中 select CustomLabel
的对象,然后选择 Editor ➔ Debug Selected Views。
您可以看到方法调用的顺序。这只是显示了界面生成器中的渲染顺序,而不是它在 运行 时间内可能遵循的顺序。
可能您知道这一点,但为了清楚起见,您可以使用以下方式在 IB 中反映这一点。
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
backgroundColor = UIColor.grayColor()
}
init(frame:)和init?(coder:)的逻辑在InterfaceBuilder渲染模式下会产生两种不同的渲染,因为IBDesignablesAgent-iOS用来渲染IBDesignable的类调用了init(frame :) 然后它使用“用户定义的 运行 时间属性”默认/自定义值来配置自定义视图。因此,在 init(frame:) 中设置的 backgroundColor 将被 Interface builder 中设置的背景颜色值 default/custom 更改。
如果应用 运行 在设备或模拟器上呈现 运行 时间,则使用 init?(coder:) 方法并在故事板的默认/自定义值之后应用“setup()”逻辑被应用。如果从代码创建自定义视图,则使用 init(frame:) 方法,但故事板的“用户定义 运行 时间属性”没有解码,因为这个不存在。
我很好奇为什么不将 backgroundColor
设置为红色?
@IBDesignable class CustomLabel: UIView {
let view = UIView()
func setup() {
backgroundColor = UIColor.red
view.backgroundColor = UIColor.green
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
addSubview(view)
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
}
这是结果。
这就是我期望的样子。
在 Interface builder(IB) 中呈现时,在调用 init
后加载自定义 UI 元素的 IB 中设置的属性。正在调用您在 init
中设置 backgroundColor
的代码。但在那之后,它再次为 IB.
backgroundColor
的值设置 backgroundColor
我找不到这方面的 Apple 文档。我这样说是基于以下分析。为了调试,我稍微修改了你的代码。
@IBDesignable class CustomLabel: UIView {
let view = UIView()
override var backgroundColor: UIColor? {
didSet {
print("here: "); // break point 1
}
}
func setup() {
self.backgroundColor = UIColor.redColor() // break point 2
view.backgroundColor = UIColor.greenColor()
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
addSubview(view)
}
override init(frame: CGRect) {
super.init(frame: frame) // break point 3
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) // break point 4
setup()
}
}
现在,将断点放在所有方法中。然后,在 Interface Builder 中 select CustomLabel
的对象,然后选择 Editor ➔ Debug Selected Views。
您可以看到方法调用的顺序。这只是显示了界面生成器中的渲染顺序,而不是它在 运行 时间内可能遵循的顺序。
可能您知道这一点,但为了清楚起见,您可以使用以下方式在 IB 中反映这一点。
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
backgroundColor = UIColor.grayColor()
}
init(frame:)和init?(coder:)的逻辑在InterfaceBuilder渲染模式下会产生两种不同的渲染,因为IBDesignablesAgent-iOS用来渲染IBDesignable的类调用了init(frame :) 然后它使用“用户定义的 运行 时间属性”默认/自定义值来配置自定义视图。因此,在 init(frame:) 中设置的 backgroundColor 将被 Interface builder 中设置的背景颜色值 default/custom 更改。 如果应用 运行 在设备或模拟器上呈现 运行 时间,则使用 init?(coder:) 方法并在故事板的默认/自定义值之后应用“setup()”逻辑被应用。如果从代码创建自定义视图,则使用 init(frame:) 方法,但故事板的“用户定义 运行 时间属性”没有解码,因为这个不存在。