Search code examples
iosswiftuikitcore-animationcashapelayer

Animate UIView from circle to pin


I need to implement an animation where I start from circle into a pin. The animation will start when I long press the circle, the circle will become a pin. When I release the view the pin will return to it's initial form (circle)

At the end it will look like: enter image description here

What's the best way to achieve this?


Solution

  • This could be a bit complex, you need to implemenment shape morphing animation using two set of UIBezierPath.

    Create two bezier paths first to define the shapes for circle and pin

    1. First prepare a UIBezierPath which defines the pin. You may need to have several call to addQuadCurve(to endPoint: CGPoint, controlPoint: CGPoint) to achive the perfect shape. Let's say this UIBezierPath as pinPath,

    2. In second step, you need to create another shape for the circle just by moving the points or changing the curves used in creating bezier path for the pin. Make sure the number of points/curves will be exactly same in both paths, the change will be in poisitions or control points. Let's call this bezier paths as circlePath.

    [YOU MAY NEED TO WORK WITH YOUR DESIGNER CLOSELY TO CREATE THESE TWO SHAPES, you can export these shapes as SVG files and conver them to UIBezierPath using http://svg-converter.kyome.io/]

    Add your shape on custom UIControl which will act as slider.

    Let's say your thumb layer is called as thumbLayer.

    let thumbLayer = CAShapeLayer()
    thumbLayer.frame = ...
    thumbLayer.fillColor = ...
    thumbLayer.strokeColor = ...
    thumbLayer.path = circlePath.cgPath
    myCustomSlider.layer.addSublayer(thumbLayer)
    

    Animate from Circle to Pin shape

    let animation = CABasicAnimation(keyPath: "path")
    animation.toValue = pinPath.cgPath
    animation.duration = 1
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    animation.isRemovedOnCompletion = false
    thumbLayer.add(animation, forKey: animation.keyPath)
    

    I hope this example gist will be helpful for you to understand the basic idea of shape morphing animation using UIBezierPath.

    enter image description here