iosswiftcashapelayer

Can I change a strokeEnd property without animation?


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


Solution

  • 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()