Search code examples
iosswiftanimationspinneruibezierpath

Filling circle animation with UIBezierPath and iOS draw rect


I have this on github: https://github.com/evertoncunha/EPCSpinnerView

It does this animations:

Spinner a nimation

There is a glitch in the animation, when the circle is filling and the view is resizing, and I wan't to fix that.

The glitch happens because the way I fill the circle by setting the layer corners, so it looks like a circle, and I increase the lineWidth with the animation progress, and it looks likes it's filling from outside in. From EPCDrawnIconSpinner.swift file:

let ovalPath = UIBezierPath()
ovalPath.addArc(withCenter: CGPoint(x: ovalRect.midX, y: ovalRect.midY),
                radius: ovalRect.width / 2,
                startAngle: start * CGFloat.pi/180,
                endAngle: end * CGFloat.pi/180, clockwise: true)
layer.cornerRadius = rect.size.height/2
ovalPath.lineWidth = 14 + ((frame.size.width) * progress)

Is there a better way that I can achieve this animation without doing the layer cornerRadius thing? If I could only draw this


Solution

  • I ended up with the following solution:

    fileprivate func drawPathCompleted(_ ovalRect: CGRect) {
    
         var size: CGFloat = ovalRect.size.width
    
         var current = size*(1-progress)
    
         var pos: CGFloat = lineWidth/2
    
         while size > current {
           let ovalPath = UIBezierPath(ovalIn: CGRect(x: pos, y: pos, width: size, height: size))
           ovalPath.lineCapStyle = .round
           ovalPath.lineWidth = lineWidth
           ovalPath.stroke()
           let decr = lineWidth/2
           size -= decr
           pos += decr/2
         }
    }
    

    At this commit, line 243: https://github.com/evertoncunha/EPCSpinnerView/commit/87d968846d92aa97e85ff4c58b6664ad7b03f00b#diff-8dc22814328ed859a00acfcf2909854bR242