Search code examples
swiftanimationprogress-barwatchkit

Watch OS: Creating a Circular Progress Bar


Is there a way to create an animated circular progress bar on the Watch? Circular Loader

I don't want to use multiple loading images to create this effect. Maybe using a Game Scene?


Solution

  • I figured it out. Used an SKScene. Created a circular path using UIBezierPath. And attached it to an SKShapeNode. Finally, animated the path using an SKAction.

    Hope this helps someone.

    
    class RestScene: SKScene {
    
    
        override func sceneDidLoad() {
    
    
            addCircle()
        }
    
    
        func addCircle() {
    
            let path = getCirclePath(ofRadius: 50, withPercent: 1)
    
            let shapeNode = SKShapeNode(path: path)
            shapeNode.strokeColor = .blue
            shapeNode.fillColor = .clear
            shapeNode.lineWidth = 4
            shapeNode.lineCap = .round
            shapeNode.position = CGPoint(x: 0, y: 0)
            shapeNode.zRotation =  CGFloat.pi * 0.5
    
            self.addChild(shapeNode)
    
    
            animateStrokeEnd(circle: shapeNode, duration: 5){
                shapeNode.path = nil
                print("Done")
            }
        }
    
        func getCirclePath(ofRadius radius :CGFloat, withPercent percent:CGFloat) -> CGPath {
           return  UIBezierPath(arcCenter: .zero,
                         radius: radius,
                         startAngle: 0,
                         endAngle: 2 * .pi * percent,
                         clockwise: true).cgPath
    
    
    
        }
    
        func animateStrokeEnd(circle:SKShapeNode, duration:TimeInterval, completion:@escaping ()->Void)  {
            guard let path = circle.path else {
                return
            }
            let radius = path.boundingBox.width/2
            let animationAction = SKAction.customAction(withDuration: duration) { (node, elpasedTime) in
                let percent =  elpasedTime/CGFloat(duration)
                (node as! SKShapeNode).path = self.getCirclePath(ofRadius: radius, withPercent: 1 - percent)
            }
    
            circle.run(animationAction) {
                completion()
            }
    
    
        }
    
    }