uiviewcore-animationuibezierpathcashapelayercadisplaylink

how to 'animate' changing shape of a view in IOS? (i.e. change it's path from one to another)


How can one 'animate' changing a custom UIView based around a shape, from one shape to another shape?

Say for example one is creating a UIView that appears like a shape, created using a UIBezierPath. But then you want this view object to change in an 'animated' style from custom shape 1 to custom shape 2? So I could create two separate paths using UIBezierPath to represent the two shapes, but I'm unclear how to 'animate' moving from one to another?

Not sure also if 'animate' is the correct term here. For example if this is inherently un-animatable then perhaps I mean 'visually morphing' the view of the object from one to another.

I'm reading up on these but still not quite seeing how: UIBezierPath, CAShapeLayer, CADisplayLink,


Solution

  • You can simply change the path property of a CAShapeLayer and it will animate using implicit animation. A display link is unnecessary for animation as the core animation subsystem handles everything for you. A display link is for when you need a high performance/accuracy timer that is synchronized with the refresh rate of your display.

    To change the path property of a CAShapeLayer, you can build up the path using a UIBezierPath object and then return its CGPath. Something like (in Swift)

    let bezier = UIBezierPath()
    bezier.moveToPoint(CGPointMake(100.0, 100.0))
    bezier.addLineToPoint(CGPointMake(150.0, 90.0))
    ...
    bezier.closePath()
    
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = bezier.CGPath
    

    Keep in mind this is real code, however, you will need to build out the properties of your shape layer for display such as bounds and position, and at a minimum you'll want to set your shape layer's strokeColor so you can see what's going on. The fillColor property would be good to set too for this same reason.

    Once you've established your initial shape (path), you can create a second bezier path that your path can animate to. Here's the rub, though. If your new path does not have the exact same number of points as your previous path, the animation likely won't do what you expect.

    Coincidentally, I've been playing with this kind of thing lately just for fun. I wrote a little bit of code to see how it works. You can grab that (Swift) code here: https://github.com/perlmunger/Morph . It does what you see in this animation. It doesn't morph in exactly the way I would expect but it provides a neat illustration nonetheless: enter image description here