Swift: UIBezierPath Stroke Animation from Center

Swift syntax changed much during these three years. Here is my updated version of originally accepted answer, but in Swift 5.1+

private extension UIBezierPath {

    convenience init(roundedRectFromCenter frame: CGRect, cornerRadius: CGFloat) {
        self.init()

        move(to: CGPoint(x: frame.width / 2, y: 0))
        addLine(to: CGPoint(x: frame.width - cornerRadius, y: 0))
        addArc(
            withCenter: CGPoint(x: frame.width - cornerRadius, y: cornerRadius),
            radius: cornerRadius,
            startAngle: -.pi / 2,
            endAngle: 0,
            clockwise: true
        )
        addLine(to: CGPoint(x: frame.width, y: frame.height - cornerRadius))
        addArc(
            withCenter: CGPoint(x: frame.width - cornerRadius, y: frame.height - cornerRadius),
            radius: cornerRadius,
            startAngle: 0,
            endAngle: .pi / 2,
            clockwise: true
        )
        addLine(to: CGPoint(x: cornerRadius, y: frame.height))
        addArc(
            withCenter: CGPoint(x: cornerRadius, y: frame.height - cornerRadius),
            radius: cornerRadius,
            startAngle: .pi / 2,
            endAngle: .pi,
            clockwise: true
        )
        addLine(to: CGPoint(x: 0, y: cornerRadius))
        addArc(
            withCenter: CGPoint(x: cornerRadius, y: cornerRadius),
            radius: cornerRadius,
            startAngle: .pi,
            endAngle: .pi * 3 / 2,
            clockwise: true
        )

        close()
        apply(CGAffineTransform(
            translationX: frame.origin.x,
            y: frame.origin.y
        ))
    }

}

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.