ios - 使用 CAShapeLayer 多次动画循环进度

标签 ios swift cashapelayer

当用户点击按钮时,我需要为圆圈的进度设置动画。我目前正在使用 CAShapeLayer 和 CABasicAnimation。代码如下:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var circleContainerView: UIView!

    var progressPts = [0.1, 0.3, 0.7, 0.5]
    let circleLayer = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupCircle()
    }

    @IBAction func didTapAnimate(_ sender: Any) {
        guard let pt = progressPts.first else { return }
        let animateStroke = CABasicAnimation(keyPath: "strokeEnd")
        animateStroke.toValue = pt
        animateStroke.duration = 2.0
        animateStroke.fillMode = .forwards
        animateStroke.isRemovedOnCompletion = false
        circleLayer.add(animateStroke, forKey: "MyAnimation")
        progressPts.removeFirst()
    }

    private func setupCircle() {
        circleLayer.frame = CGRect(origin: .zero, size: circleContainerView.bounds.size)
        let center = CGPoint(x: circleLayer.bounds.width / 2.0,
                             y: circleLayer.bounds.height / 2.0)
        circleLayer.path = UIBezierPath(arcCenter: center,
                                        radius: (circleLayer.bounds.height / 2.0) - 5.0,
                                        startAngle: 0,
                                        endAngle: 2 * CGFloat.pi, clockwise: true).cgPath
        circleLayer.fillColor = UIColor.clear.cgColor
        circleLayer.lineWidth = 10.0
        circleLayer.strokeColor = UIColor.red.cgColor
        circleLayer.strokeEnd = 0.0
        circleContainerView.layer.addSublayer(circleLayer)
    }

}

为了在动画结束时笔画保持在正确的位置,我需要将 fillMode 也设置为 .forwardsisRemovedOnCompletion。这对于第一个动画效果很好。然而,在下一个动画中,笔触首先重置:

enter image description here

我在这里做错了什么?如何在不重置的情况下为每个新的进度位置设置动画?另外,将 isRemovedOnCompletion 设置为 false 当然不是一个好主意,因为该图层最终会附加多个动画。

最佳答案

我刚刚使用 from value 属性来完成圆而不重置,只需使用下面的代码即可顺利动画

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var circleContainerView: UIView!
    var progressPts = [0.1, 0.3, 0.7, 0.5]
    var previousPts = 0.0
    let circleLayer = CAShapeLayer()
    var animateStroke: CABasicAnimation! 
    override func viewDidLoad() {
            super.viewDidLoad()
            setupCircle()
        }

        @IBAction func didTapAnimate(_ sender: Any) {
            guard let pt = progressPts.first else { return }
            animateStroke.fromValue = previousPts
            animateStroke.toValue = pt
            animateStroke.duration = 2.0
            animateStroke.fillMode = .forwards
            animateStroke.isRemovedOnCompletion = false
            circleLayer.add(animateStroke, forKey: "MyAnimation")
            previousPts = progressPts.removeFirst()
        }

        private func setupCircle() {
             animateStroke =  CABasicAnimation(keyPath: "strokeEnd")
            circleLayer.frame = CGRect(origin: .zero, size: circleContainerView.bounds.size)
            let center = CGPoint(x: circleLayer.bounds.width / 2.0,
                                 y: circleLayer.bounds.height / 2.0)
            circleLayer.path = UIBezierPath(arcCenter: center,
                                            radius: (circleLayer.bounds.height / 2.0) - 5.0,
                                            startAngle: 0,
                                            endAngle: 2 * CGFloat.pi, clockwise: true).cgPath
            circleLayer.fillColor = UIColor.clear.cgColor
            circleLayer.lineWidth = 10.0
            circleLayer.strokeColor = UIColor.red.cgColor
            circleLayer.strokeEnd = 0.0
            circleContainerView.layer.addSublayer(circleLayer)
        }

    }

输出

enter image description here

关于ios - 使用 CAShapeLayer 多次动画循环进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56945102/

相关文章:

ios - 如何使用 Facebook SDK 4+ 和 Parse 访问 "first_name"权限

iOS ScrollView 截图

ios - MMDrawerController触摸UISlider应用于iOS 7上的错误 View

swift - 使用 objectWithID 获取所有值为 null 的托管对象

ios - CABasicAnimation CALayer 路径动画方向

ios - 只绘制 ImageVIew 框架的角

ios - Xcode UI 测试导致每台 iOS 设备崩溃

swift - 如何在 Swift 中创建唯一对象列表数组

swift - 为什么 Swift JSONDecodable 会失败?

iOS "erase"使用 CAShapeLayer 动画绘图