帧大小和所需的init(编码器:NSCoder)'在自定义UIControl中

时间:2015-04-17 06:18:40

标签: ios swift

我有一个自定义的UIControl,我实现为:

required init(coder: NSCoder) {
    super.init(coder: coder)
    initSubComponents()
}

func initSubComponents() {
    // Display UIControl border for visual debugging
    self.layer.borderColor = UIColor.redColor().CGColor
    self.layer.borderWidth = 3.0

    subviewContainer = UIView(frame: self.bounds.rectByInsetting(dx: 0, dy: 0))
    // Display container border for visual debugging
    subviewContainer.layer.borderColor = UIColor.redColor().CGColor
    subviewContainer.layer.borderWidth = 3.0

    println("UIControl frame: \(self.frame)")
    println("subviewContainer frame: \(subviewContainer.frame)")
}

override func drawRect(rect: CGRect) {
    initSubComponents()
    // Code to add those subviews into this UIControl
}

func initSubComponents() {
    // Display UIControl border for visual debugging
    self.layer.borderColor = UIColor.redColor().CGColor
    self.layer.borderWidth = 3.0

    subviewContainer = UIView(frame: self.bounds.rectByInsetting(dx: 0, dy: 0))
    // Display container border for visual debugging
    subviewContainer.layer.borderColor = UIColor.redColor().CGColor
    subviewContainer.layer.borderWidth = 3.0

    println("UIControl frame: \(self.frame)")
    println("subviewContainer frame: \(subviewContainer.frame)")
}

我发现了一个我不明白的情况:我从上述两种不同的方法得到的框架是不同的!为什么?第一种方法应该更好,因为我不应该在override func drawRect(rect: CGRect)初始化,但是我在第二种方法中得到了我期望的确切帧,而不是第一种方法!

2 个答案:

答案 0 :(得分:2)

这种情况正在发生,因为在初始化控件是从storyboard / nib获取它的帧。故事板/笔尖中视图的大小可能与设备上的大小不同,直到第一次布局为止。

正如评论中的人所说,drawRect被不断调用,因此它具有正确的框架,因为控件已经布局。但这是初始化子组件的错​​误位置。另外,作为默认实现,除非您实际在drawRect中绘制内容,否则您不应该使用它,因为它会对性能产生负面影响。

我现在可以想到你的问题有几个解决方案:

  1. 使用约束初始化initWithCoder方法中的子组件,并在布局控件时依赖autolayout更新所有内容。
  2. 使用标志仅初始化子组件一次。等待layoutSubviews中的第一个布局并从那里初始化。

答案 1 :(得分:0)

  

一个好的解决方案是为您添加自动布局约束   subviewContainer,因为约束每次都会自动更新   时间self.frame更改。

您的代码将是这样的:

required init(coder: NSCoder) {
    super.init(coder: coder)
    initSubComponents()
}

func initSubComponents() {

    // Original code, I removed debugging code for easier reading.
    subviewContainer = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

    //Where the magic happens:
    subviewContainer.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint(item: subviewContainer, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: 0).isActive = true
    NSLayoutConstraint(item: subviewContainer, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1.0, constant: 0).isActive = true
    NSLayoutConstraint(item: subviewContainer, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subviewContainer, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
}

有更多方法可以添加自动布局约束click to find out here

  

这是一个更多的代码,但一般来说是一个更好的方法来处理这个问题   问题,因为有些情况drawRect不会来   救援。