@IBDesignable视图在Interface Builder中无法绘制背景颜色

12

我很好奇为什么这个代码没有把 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()
  }
}

这是结果。

在此输入图片描述

而我希望它看起来像这样。

在此输入图片描述

3个回答

19

在使用界面编辑器(IB)渲染时,自定义 UI 元素中设置的属性会在调用 init 后加载。你在 init 中设置 backgroundColor 的代码被调用了。但在那之后,它又将 backgroundColor 重新设置为 IB 中 backgroundColor 属性的值。

我没有找到苹果文档来证实这一点。这是基于我的分析所得到的结论。我修改了你的代码以进行调试。

@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()
    }
}

现在,在所有方法中设置断点。然后,在界面构建器中选择CustomLabel对象,选择编辑器 ➔ 调试选定视图。

您可以看到方法调用的顺序。这只是显示界面构建器中呈现顺序的顺序,并不是运行时可能遵循的顺序。

也许您已经知道这一点,但为了清晰起见,您可以使用以下方法在IB中反映出这一点。

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    backgroundColor = UIColor.grayColor()

}

1

在InterfaceBuilder渲染模式下,init(frame:)和init?(coder:)的逻辑会产生两种不同的渲染结果,因为用于渲染IBDesignable类的IBDesignablesAgent-iOS会调用init(frame:),然后使用“用户定义的运行时属性”默认/自定义值来配置自定义视图。因此,在init(frame:)中设置的backgroundColor将被Interface builder中设置的背景颜色的默认/自定义值更改。

在运行时渲染时,应用程序在设备或模拟器上运行时会使用init?(coder:)方法,并且在应用默认/自定义值之后应用“setup()”逻辑。如果从代码创建自定义视图,则使用init(frame:)方法,但是没有从故事板的“用户定义的运行时属性”进行解码,因为这个不存在。


1
在Interface Builder和运行时,渲染的行为略有不同。IBDesignablesAgent-iOS用于在Interface Builder中呈现IBDesignable类,它调用init(frame:),然后使用“用户定义的运行时属性”默认/自定义值来配置自定义视图。这意味着在init(frame:)中设置的背景颜色将被Interface Builder中设置的背景颜色的默认/自定义值更改,并且后者是您在Interface Builder中看到的呈现效果。
这与运行时发生的呈现逻辑不同(当应用程序在设备或模拟器上运行时)。在此处,Interface Builder中设置的默认/自定义值在调用init?(coder:)方法之后应用。这意味着在init?(coder:)中设置的背景颜色是您在设备上看到的呈现效果。
(感谢@Blazej)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接