进度圈持续时间与预期不符

Progress circle duration is not like expected

我希望视图圈进度的持续时间恰好持续 1 秒,但在我的应用中,它只持续约 0.84 秒。

动图:

在 viewDidLoad 中:

    let shapeLayer = CAShapeLayer()

    let center = view.center
    let trackLayer = CAShapeLayer()
    let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
    trackLayer.path = circularPath.cgPath
    trackLayer.strokeColor = UIColor.lightGray.cgColor
    trackLayer.lineWidth = 10
    trackLayer.fillColor = UIColor.clear.cgColor
    trackLayer.lineCap = kCALineCapRound
    view.layer.addSublayer(trackLayer)
    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.red.cgColor
    shapeLayer.lineWidth = 10
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineCap = kCALineCapRound
    shapeLayer.strokeEnd = 0
    view.layer.addSublayer(shapeLayer)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))

如果您点击屏幕:

@objc private func handleTap() {
    let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
    basicAnimation.toValue = 1

    ///Here is defined the duration
    basicAnimation.duration = 1

    basicAnimation.fillMode = kCAFillModeForwards
    basicAnimation.isRemovedOnCompletion = false

    shapeLayer.add(basicAnimation, forKey: "urSoBasic")
}

我也试过:

basicAnimation.duration = CFTimeInterval(1)

但效果不佳。

它必须持续1秒,可能它已经运行宁了0.15秒左右才看到。 ViewDidLoad 并不代表你看到了。尝试将 beginTime 设置为 CACurrentMediaTime() + 2.0 并再次测量。或者 运行 这个视图确实以 CACurrentMediaTime() 的 beginTime 出现。

更新: 使用您的代码

import UIKit

class ViewController: UIViewController {

    var shapeLayer = CAShapeLayer()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        shapeLayer = CAShapeLayer()

        let center = view.center
        let trackLayer = CAShapeLayer()
        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
        trackLayer.path = circularPath.cgPath
        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = kCALineCapRound
        view.layer.addSublayer(trackLayer)
        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.strokeEnd = 0
        view.layer.addSublayer(shapeLayer)
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    }


    @objc private func handleTap() {
        //prints //the time when the animation start is 30830.886492681
        print("the time when the animation start is \(CACurrentMediaTime())")
        CATransaction.begin()
        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
        basicAnimation.toValue = 1
        ///Here is defined the duration
        basicAnimation.duration = 1
        basicAnimation.fillMode = kCAFillModeForwards
        basicAnimation.isRemovedOnCompletion = false
        //here i make sure it starts at the current time
        basicAnimation.beginTime = CACurrentMediaTime()
        CATransaction.setCompletionBlock {
            //prints the current Time is 30831.895261542
            print("the current Time is \(CACurrentMediaTime())")
        }
        shapeLayer.add(basicAnimation, forKey: "urSoBasic")
        CATransaction.commit()
    }


}

在我的示例中,它持续了多一毫秒,尽管我敢打赌动画实际开始时存在帧差异。请记录你的而不是使用视频,看看它是否持续了它应该持续的时间。如果不是,我们还缺少什么其他代码。您还有其他可能阻塞主线程的东西吗?