22

I can't seem to remove the animation from the strokeEnd property of my CAShapeLayer.

The documentation says the property is animatable but not that is animated by default and I can't pinpoint the problem. Any suggestions where to look?

Here's my code:

class ViewController: UIViewController {

    let circle = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Circle
        circle.fillColor = UIColor.clearColor().CGColor
        circle.strokeColor = UIColor.blackColor().CGColor
        circle.lineWidth = 10
        circle.strokeEnd = 0
        circle.lineJoin = kCALineJoinRound
        circle.path = UIBezierPath(ovalInRect: CGRectMake(60, 140, 200, 200)).CGPath
        circle.actions = ["strokeEnd" : NSNull()]

        // Show Button
        let showButton = UIButton(frame: CGRectMake(40, 40, 240, 40))
        showButton.addTarget(self, action: "showButton", forControlEvents: UIControlEvents.TouchUpInside)
        showButton.setTitle("Show circle", forState: UIControlState.Normal)
        showButton.backgroundColor = UIColor.greenColor()

        // Add to view
        self.view.layer.insertSublayer(circle, atIndex: 1)
        self.view.addSubview(showButton)
    }

    func showButton() {
        circle.strokeEnd = 1
    }
}

CAShapeLayer strokeEnd animation

Tieme
  • 62,602
  • 20
  • 102
  • 156

2 Answers2

40

The approach you describe of setting the layer's strokeEnd action to NSNull works but it's a bit of a sledgehammer. When you do that you kill implicit animation of the strokeEnd property of your layer forever.

If that's what you want, that's ok. However, I tend to prefer using the second approach that David Rönnqvist lists in the answer you linked: Making your layer change inside a CATransaction begin/commit block. Here is the code for that from David's answer (which is excellent, as his posts always are).

[CATransaction begin];
[CATransaction setDisableActions:YES];
// change your property here 
yourShapeLayer.strokeEnd = 0.7;
[CATransaction commit]; // animations are disabled until here...

That code is in Objective-C. Translating it to Swift isn't too bad:

CATransaction.begin()
CATransaction.setDisableActions(true)
yourShapeLayer.strokeEnd = 0.7
CATransaction.commit()
Duncan C
  • 128,072
  • 22
  • 173
  • 272
5

I've found the problem. This solves it:

circle.actions = ["strokeEnd" : NSNull()]

More info can be found here: Change CAShapeLayer without Animation

Community
  • 1
  • 1
Tieme
  • 62,602
  • 20
  • 102
  • 156
  • 1
    The approach you describe of setting the layer's strokeEnd action to NSNull works but it's a bit of a sledgehammer. It permanently removes changes to the strokeEnd property from this and all future animations. See my answer for an alternative. – Duncan C Dec 11 '18 at 18:20
  • Fair enough. I found your answer recently and wanted to document the pros and cons of the different approaches for other readers though. – Duncan C Dec 18 '18 at 00:32