Sunday, May 8, 2016

Swift: UIBezierPath Stroke Animation from Center

Leave a Comment

I've been making a simple UIBezierPath animation with Swift. This path consists on creating a rounded rectangle with a colored border. The animation must be the drawing of the colored border. To do so, I've created a CAShapeLayer with a UIBezierPath(roundedRect:, cornerRadius: )

let layer = CAShapeLayer() var viewPrueba = UIView()  override func viewDidLoad() {     super.viewDidLoad()     // Do any additional setup after loading the view, typically from a nib.      viewPrueba = UIView(frame: CGRectMake(self.view.frame.width/2-100, self.view.frame.height/2 - 100, 200, 200))     self.view.addSubview(viewPrueba)     let path = UIBezierPath(roundedRect: CGRectMake(0, 0, 200, 200), cornerRadius: 40.0)     layer.path = path.CGPath     layer.fillColor = UIColor.clearColor().CGColor     layer.strokeColor = UIColor.blueColor().CGColor     layer.strokeStart = 0.0     layer.strokeEnd = 0.0     layer.lineWidth = 4.0     layer.lineJoin = kCALineJoinRound     viewPrueba.layer.addSublayer(layer)     let tapGR = UITapGestureRecognizer(target: self, action: #selector(ViewController.anim))     self.view.addGestureRecognizer(tapGR) }  func anim() {     let anim1 = CABasicAnimation(keyPath: "strokeEnd")     anim1.fromValue         = 0.0     anim1.toValue           = 1.0     anim1.duration          = 4.0     anim1.repeatCount       = 0     anim1.autoreverses      = false     anim1.removedOnCompletion = false     anim1.additive = true     anim1.fillMode = kCAFillModeForwards     self.layer.addAnimation(anim1, forKey: "strokeEnd") }` 

It works well. The only problem is that the animation starts from the top-left part of the square and not from the top-center. How can I do that?

The only thing I've found in order to achieve this is by doing it with a circle and not a rectangle, which is not what we want.

This is where the animation starts

Thanks

1 Answers

Answers 1

CoreAnimate animated as the same order as which the UIBezierPath was drawn.
The system method

+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;      

return a UIBezierPath which was drawn from the top-left,so your animation started from the top-left.
But you can create your own UIBezierPath drawn form top-center:

func centerStartBezierPath(frame:CGRect,cornerRadius:CGFloat) -> UIBezierPath {     let path = UIBezierPath()     path.moveToPoint(CGPointMake(frame.width/2.0, 0))     path.addLineToPoint(CGPointMake(frame.width-cornerRadius, 0))     path.addArcWithCenter(CGPointMake(frame.width-cornerRadius, cornerRadius),                           radius: cornerRadius,                           startAngle: CGFloat(-M_PI/2),                           endAngle: 0,                           clockwise: true)     path.addLineToPoint(CGPointMake(frame.width, frame.height-cornerRadius))     path.addArcWithCenter(CGPointMake(frame.width-cornerRadius, frame.height-cornerRadius),                           radius: cornerRadius,                           startAngle: 0,                           endAngle: CGFloat(M_PI/2),                           clockwise: true)     path.addLineToPoint(CGPointMake(cornerRadius, frame.height))     path.addArcWithCenter(CGPointMake(cornerRadius, frame.height-cornerRadius),                           radius: cornerRadius,                           startAngle: CGFloat(M_PI/2),                           endAngle: CGFloat(M_PI),                           clockwise: true)     path.addLineToPoint(CGPointMake(0, cornerRadius))     path.addArcWithCenter(CGPointMake(cornerRadius, cornerRadius),                           radius: cornerRadius,                           startAngle: CGFloat(M_PI),                           endAngle: CGFloat(M_PI*3/2),                           clockwise: true)     path.closePath()      path.applyTransform(CGAffineTransformMakeTranslation(frame.origin.x, frame.origin.y))      return path; }     

And it works like this: top-center start animation
You can also change the code,and start from any point you want.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment