iosswiftcore-graphics

draw#rect core graphics, on top of a layer?


Say you have this in a UIView,

override func draw(_ rect: CGRect) {
    super.draw(rect) // (always worth remembering)
    let c = UIGraphicsGetCurrentContext()
    c?.setLineWidth(10)
    c?.move(to: CGPoint(x: 42, y: 42))
    c?.addLine(to: CGPoint(x: 69, y: 69))
    c?.strokePath()
}

Of course, it will draw the hell out of your drawing for you.

However, if in the same UIView you ...

thingLayer = CAShapeLayer()
self.layer.insertSublayer(thingLayer, at: 0)
...

... in fact, any material in added layers appears on top of your drawing in draw#rect.

Is there a way to have the drawing done in draw#rect be drawn on TOP of any added layers?


Solution

  • Bottom line, the draw(_:) is for rendering the root view of a UIView subclass. If you add sublayers, they will be rendered on top of whatever is done in the root view’s draw(_:).

    If you have a few paths currently performed in the draw(_:) that you want to render on top of the sublayer that you’ve added, you have a few options:

    1. Move the paths to be stroked in their own CAShapeLayer instances and add them above the other sublayer that you’ve already added.

    2. Consider the main UIView subclass as a container/content view, and add your own private UIView subviews (potentially with the “complicated” draw(_:) methods). You don’t have to expose these private subviews if you don’t want to.

    3. Move the complicated drawing to the draw(in:) of a CALayer subclass and, again, add this sublayer above the existing sublayer that you’ve already created.

    4. Given that the thingLayer is, effectively, only setting the background color, you could just set the background color of the view and not use a layer for this background color at all.