【问题标题】:@IBDesignable view doesn't draw background color inside Interface Builder@IBDesignable 视图不会在 Interface Builder 中绘制背景颜色
【发布时间】:2016-09-06 10:53:13
【问题描述】:

我很好奇为什么不将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()
  }
}

这是结果。

这就是我期望的样子。

【问题讨论】:

    标签: ios swift interface-builder ibdesignable


    【解决方案1】:

    在 Interface builder(IB) 中渲染时,在调用 init 后加载自定义 UI 元素的 IB 中设置的属性。您在init 中设置backgroundColor 的代码被调用。但在那之后,它再次将backgroundColor 设置为IB 中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 中选择 CustomLabel 的对象,然后选择 Editor ➔ Debug Selected Views。

    您可以看到方法调用的顺序。这只是显示了界面生成器中的渲染顺序,而不是它在运行时可能遵循的顺序。

    您可能知道这一点,但为了清楚起见,您可以使用以下内容在 IB 中反映这一点。

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

    【讨论】:

      【解决方案2】:

      init(frame:) 和 init?(coder:) 的逻辑导致 InterfaceBuilder 渲染模式下的两种不同渲染,因为用于渲染 IBDesignable 类的 IBDesignablesAgent-iOS 调用 init(frame:) 之后它使用 "用户定义的运行时属性”默认/自定义值来配置自定义视图。因此,在 init(frame:) 中设置的 backgroundColor 将根据 Interface builder 中设置的背景颜色的默认/自定义值进行更改。 如果应用程序在设备或模拟器上运行时进行运行时渲染,则使用 init?(coder:) 方法并在应用故事板的默认/自定义值后应用“setup()”逻辑。如果从代码创建自定义视图,则使用 init(frame:) 方法,但没有从情节提要的“用户定义的运行时属性”解码,因为这个不存在。

      【讨论】:

        猜你喜欢
        • 2014-08-01
        • 1970-01-01
        • 2019-09-04
        • 1970-01-01
        • 1970-01-01
        • 2020-04-21
        • 1970-01-01
        相关资源
        最近更新 更多