I have a custom UIControl, and I implement as:
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)")
}
or
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)")
}
I found a situation that I don't understand: the frame I got from the above 2 different approaches are different! Why? The first approach should be better, cause I should not init in override func drawRect(rect: CGRect)
, however I got the exact frame I expect in the second approach, not the first approach!
This is happening because on init the control is getting it's frame from the storyboard/nib. The size of the view in the storyboard/nib can be different than the size on a device until it is laid out for the first time.
As people in the comments have stated drawRect
is constantly being called, and so it has the correct frame because the control has already been laid out. But this is the wrong place to initialize sub components. Also as the default implementation states, unless you are actually drawing something in drawRect
you shouldn't use it since it adversely affects performance.
There are a couple of solutions to you your problem I can think of right now:
initWithCoder
method with constraints and rely on autolayout updating everything when the control is laid out.layoutSubviews
and initialize from there.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With