我有一个自定义的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)
初始化,但是我在第二种方法中得到了我期望的确切帧,而不是第一种方法!
答案 0 :(得分:2)
这种情况正在发生,因为在初始化控件是从storyboard / nib获取它的帧。故事板/笔尖中视图的大小可能与设备上的大小不同,直到第一次布局为止。
正如评论中的人所说,drawRect
被不断调用,因此它具有正确的框架,因为控件已经布局。但这是初始化子组件的错误位置。另外,作为默认实现,除非您实际在drawRect
中绘制内容,否则您不应该使用它,因为它会对性能产生负面影响。
我现在可以想到你的问题有几个解决方案:
initWithCoder
方法中的子组件,并在布局控件时依赖autolayout更新所有内容。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
不会来 救援。