When i override draw(_ rect: CGRect) and leave it empty, then it happens that draw(_ layer: CALayer, in ctx: CGContext) got called. And circle is painted.
Here is the code. I just assigned SpecialView class to view in IB.
class SpecialView : UIView {
override func draw(_ rect: CGRect) {
}
override func draw(_ layer: CALayer, in ctx: CGContext) {
UIGraphicsPushContext(ctx)
let p = UIBezierPath(ovalIn: CGRect(0,0,100,100))
UIColor.blue.setFill()
p.fill()
UIGraphicsPopContext()
}
}
But when i do not override draw(_ rect: CGRect), and just leave the code as below in code snippet:
class SpecialView : UIView {
override func draw(_ layer: CALayer, in ctx: CGContext) {
UIGraphicsPushContext(ctx)
let p = UIBezierPath(ovalIn: CGRect(0,0,100,100))
UIColor.blue.setFill()
p.fill()
UIGraphicsPopContext()
}
}
The draw(_ layer: CALayer, in ctx: CGContext) function is not called. And circle is not got painted.
Do you know why?
Layers are very lazy about drawing. They do not draw unless you tell them that they need to. So, you could solve the problem here by explicitly telling the layer setNeedsDisplay
.
However, views are a little more proactive. They redraw themselves automatically under certain circumstances, like when they first appear. Since this layer is the underlying layer of a view, you can get the layer to participate in that automatic redrawing if you can get the view to redraw itself automatically.
But (and this is the important part) the runtime, for the sake of efficiency, assumes that if a view has no drawRect
implementation, it does not need automatic redrawing.
So there's your answer:
Normally, a layer would not redraw at all until you tell it to.
By providing a drawRect
implementation, even though it is empty, you tell the view to redraw itself automatically when needed.
This is the view's underlying layer, so it is redrawn with the view.