Fattie
Fattie

Reputation: 12296

To clear drawing in drawRect shape-layer drawing

To save time for anyone googling here, I incorrectly thought that clearsContextBeforeDrawing would also clear any layers added in drawRect. It does not.

Of course as Matt has explained, you should certainly only draw the ordinary way in drawRect, and then clearsContextBeforeDrawing works correctly. Example,

override func drawRect(rect: CGRect)
    {
    // clearsContextBeforeDrawing works perfectly here as normal
    // don't add any layers in here :)

    let dotPath = UIBezierPath(ovalInRect:rect)
    mainColor.setFill()
    dotPath.fill()
    let ins:CGFloat = ( ringThickness / 2 )
    let circlePath = UIBezierPath(ovalInRect: CGRectInset(rect,ins,ins) )
    circlePath.lineWidth = ringThickness
    ringColor.setStroke()
    circlePath.stroke()
    }

Here's a poor way to draw in drawRect

override func drawRect(rect: CGRect)
    {
    let circlePath = UIBezierPath(ovalInRect:rect)
    let circle = CAShapeLayer()
    circle.path = circlePath.CGPath
    circle.fillColor = someColor.CGColor
    layer.addSublayer(circle)

    ... and a few more layers like ...
    blah.fillColor = someColor.CGColor
    layer.addSublayer(blah)
    }

But how to clear before drawing?

Setting clearsContextBeforeDrawing does nothing.

The only way I can clear is by removing all the layers:

override func drawRect(rect: CGRect)
    {
    // first remove all layers...
    if let sublayers = layer.sublayers {
        for layer in sublayers {
            if layer.isKindOfClass(CAShapeLayer) //(essential)
                { layer.removeFromSuperlayer() }
        }
    }
    ...
    }

Is there a better way to clear the "layer" drawing?

Upvotes: 1

Views: 1432

Answers (1)

matt
matt

Reputation: 536009

Here's a typical way to draw in drawRect

No, it isn't. It's totally atypical — and totally wrong.

The only thing you should be doing in drawRect is drawing into the current context. For example:

let circlePath = UIBezierPath(ovalInRect:rect)
circlePath.stroke() // draws into the current context

But your code is about something else entirely: you're creating a bunch of additional layers. And that's exactly what's wrong with it, and why you're left scratching your head about the way things seems to behave. If you were doing the correct thing in drawRect, you'd find that indeed whenever it is called, the drawing in the view is cleared. Your drawing in your view is not being cleared because you have no drawing in your view. Everything is in these extra layers.

So, start over. Learn to use drawRect correctly. Either draw directly into the current context, or put your layer-management code elsewhere; but don't combine them by doing your layer-management in drawRect.

Upvotes: 5

Related Questions