使用CAShapelayer的循环计时器

时间:2018-02-07 05:39:30

标签: ios swift geometry

尝试使用此

为我的应用创建一个循环计时器
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. 列出项目 这是从我的代码得到的输出:
  2. Here is the output got from my code

    此代码中遇到的主要问题是

    1. 绘制圆圈时手机正在变热
    2. 画完一半后,溺水速度下降
    3. 请帮我替代

3 个答案:

答案 0 :(得分:2)

试试这个:

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)
    }


}

UIView中取Storyboard并将其添加为子视图。然后,您可以使用showProgress函数来增加进度。

答案 1 :(得分:1)

您不应在drawRect:中添加图层。每次绘制视图时,都要添加图层。这就是为什么你的iPhone正在遭受它并且变得越来越热,这并不奇怪。您应该在viewDidLoad或创建视图的位置创建图层,而不应在drawRect中修改它们。这种方法用于绘图而不是其他任何内容。

答案 2 :(得分:0)

我这样做,为我工作。我们需要两层,一层是圆形,另一层是进步。

private let circularProgressView = UIView()
private let circleLayer = CAShapeLayer()
private let progressLayer = CAShapeLayer()
private var circularPath: UIBezierPath?

    private func setupCircularProgressBar() {
    circularPath = UIBezierPath(arcCenter: CGPoint(x: circularProgressView.frame.size.width / 2.0,
                                                   y: circularProgressView.frame.size.height / 2.0),
                                radius: circularProgressView.bounds.width / 2, startAngle: -.pi / 2,
                                endAngle: 3 * .pi / 2, clockwise: true)
    
    circleLayer.path = circularPath?.cgPath
    circleLayer.fillColor = UIColor.clear.cgColor
    circleLayer.lineCap = .round
    circleLayer.lineWidth = 5
    circleLayer.strokeColor = UIColor.darkGray.cgColor
    
    progressLayer.path = circularPath?.cgPath
    progressLayer.fillColor = UIColor.clear.cgColor
    progressLayer.lineCap = .round
    progressLayer.lineWidth = 3
    progressLayer.strokeEnd = 0
    progressLayer.strokeColor = UIColor.white.cgColor
    
    circularProgressView.layer.addSublayer(circleLayer)
    circularProgressView.layer.addSublayer(progressLayer)
}

private func animateCircularProgress(duration: TimeInterval) {
    let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
    circularProgressAnimation.duration = duration
    circularProgressAnimation.toValue = 1
    circularProgressAnimation.fillMode = .forwards
    circularProgressAnimation.isRemovedOnCompletion = false
    progressLayer.add(circularProgressAnimation, forKey: "progressAnim")
}

用法非常简单,您只需使用时间间隔为5秒钟的时间间隔参数调用animateCircularProgress方法即可:animateCircularProgress(duration: 5)

相关问题