Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular timer using CAShapelayer

Tried to create a circular timer for my app end up with this

override func drawRect(rect: CGRect) {

    let context = UIGraphicsGetCurrentContext()

    let progressWidth: CGFloat = 10;

    let centerX = CGRectGetMidX(rect)
    let centerY = CGRectGetMidY(rect)
    let center: CGPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))
    let radius: CGFloat = rect.width / 2


    var circlePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
    let backgroundCircle = CAShapeLayer()




    backgroundCircle.path = circlePath.CGPath
    backgroundCircle.fillColor = backgroundCircleFillColor
    self.layer.addSublayer(backgroundCircle)

    circlePath = UIBezierPath(arcCenter: center, radius: radius-progressWidth/2, startAngle: -CGFloat(GLKMathDegreesToRadians(90)), endAngle:CGFloat(GLKMathDegreesToRadians(currentAngle)), clockwise: true)
    let progressCircle = CAShapeLayer()
    progressCircle.path = circlePath.CGPath
    progressCircle.lineWidth = progressWidth
    progressCircle.strokeColor = progressCircleStrokeColor
    progressCircle.fillColor = UIColor.clearColor().CGColor
    self.layer.addSublayer(progressCircle)


    let innerCirclePath = UIBezierPath(arcCenter: center, radius: radius-progressWidth, startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)

    let innerCircle = CAShapeLayer()
    innerCircle.path = innerCirclePath.CGPath
    innerCircle.fillColor = innerCircleFillColor

    self.layer.addSublayer(innerCircle)
}
  1. List item Here is the output got from my code:

Here is the output got from my code

Main problems faced in this code are

  1. Phone is getting heat while drawing the circle
  2. After drawning half of the circle drowning speed decreased

Please help me with an alternative

like image 780
Midhun Narayan Avatar asked Oct 16 '25 01:10

Midhun Narayan


1 Answers

Try this :

import UIKit

class CircularProgressBar: UIView {

    let shapeLayer       = CAShapeLayer()
    let secondShapeLayer = CAShapeLayer()
    var circularPath: UIBezierPath?

    override init(frame: CGRect) {
        super.init(frame: frame)
        print("Frame: \(self.frame)")
        makeCircle()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        makeCircle()
    }

    func makeCircle(){
        let circularPath = UIBezierPath(arcCenter: .zero, radius: self.bounds.width / 2, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeColor = UIColor.orange.cgColor//UIColor.init(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0).cgColor
        shapeLayer.lineWidth = 5.0
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.strokeEnd = 0
        shapeLayer.position = self.center
        shapeLayer.transform = CATransform3DRotate(CATransform3DIdentity, -CGFloat.pi / 2, 0, 0, 1)
        self.layer.addSublayer(shapeLayer)

    }


    func showProgress(percent: Float){
        shapeLayer.strokeEnd = CGFloat(percent/100)
    }


}

Take a UIView in Storyboard and add it as a subView. Then you can increase the progress using showProgress function.

like image 118
Sharad Chauhan Avatar answered Oct 17 '25 15:10

Sharad Chauhan