CABasicAnimation 问题

Issue with CABasicAnimation

所以基本上我是在尝试创建 dialogView。此 dialogView 将包含一个加载微调器和一些将根据状态更新的文本。我按照两个指南使用 CAShapeLayer 绘制一个圆,然后围绕它制作一条线。

Link 到 code/guides 我关注了 https://www.youtube.com/watch?v=O3ltwjDJaMk https://github.com/vinayjn/Spinner/blob/master/Spinner.swift

尽管遵循了这些教程中的大部分内容。我的动画不起作用。目前它只是这个样子,不会旋转。

class LoginDialogView: UIViewController {
    lazy var loaderView: UIView = {
        let loaderView = UIView()
        loaderView.backgroundColor = .yellow
        return loaderView
    }()

    lazy var dialogTitle : UILabel = {
        let dialogTitle = UILabel()
        dialogTitle.text = "Apples"
        dialogTitle.font =  UIFont.systemFont(ofSize: 24.0)
        dialogTitle.textAlignment = .left
        dialogTitle.numberOfLines = 1
        return dialogTitle
    }()

    private var shouldAddSublayer: Bool {
           /*
            check if:
            1. we have any sublayers at all, if we don't then its safe to add a new, so return true
            2. if there are sublayers, see if "our" layer is there, if it is not, return true
           */
           guard let sublayers = loaderView.layer.sublayers else { return true }
           return sublayers.filter({ [=10=].name == "progress"}).count == 0
       }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
    }
    override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
        if shouldAddSublayer {
            setupCircleLayers()
        }
    }

    fileprivate func setupView() {
        view.backgroundColor = .red
        view.layer.cornerRadius = 20

        view.addSubview(loaderView)
        loaderView.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(10)
            make.centerX.equalTo(view.safeAreaLayoutGuide.snp.centerX)
            make.height.width.equalTo(100)
        }
    }

    private func setupCircleLayers() {
        let trackLayer = createCircleShapeLayer(strokeColor: UIColor.init(red: 56/255, green: 25/255, blue: 49/255, alpha: 1), fillColor: #colorLiteral(red: 0.9686274529, green: 0.78039217, blue: 0.3450980484, alpha: 1))
        loaderView.layer.addSublayer(trackLayer)
        startAnimating()
    }

    private func startAnimating(){
        animateRing()
    }

    private func animateRing(){
        let rotationAnimation = CABasicAnimation(keyPath: "strokeEnd")
        rotationAnimation.fromValue = 0 * (CGFloat.pi / 180)
        rotationAnimation.toValue = 360 * (CGFloat.pi / 180)
        rotationAnimation.duration = 1.6
        rotationAnimation.repeatCount = HUGE
        loaderView.layer.add(rotationAnimation, forKey: "strokeEnd")
    }

    private func createCircleShapeLayer(strokeColor: UIColor, fillColor: UIColor) -> CAShapeLayer {
        let centerpoint = CGPoint.zero
        let circularPath = UIBezierPath(arcCenter: centerpoint, radius: 30, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
        let layer = CAShapeLayer()
        layer.path = circularPath.cgPath
        layer.fillColor = fillColor.cgColor
        layer.strokeColor = strokeColor.cgColor
        layer.strokeStart = 0
        layer.strokeEnd = 0.5
        layer.lineCap = .round
        layer.lineWidth = 5
        layer.position = CGPoint(x: loaderView.frame.size.width / 2, y: loaderView.frame.size.height / 2)
        layer.name = "progress"
        return layer
    }

}

我查看并比较了代码几次,但看不出我所做的有什么不同。所以我的问题是任何人都可以查看这段代码并找出我做错了什么吗?谁能推荐一种不会导致任何潜在内存泄漏的安全方法来停止此动画?

我正在使用 ios 13 和 xcode 11.3.1

您没有将动画添加到形状图层;您将它添加到容器视图的层。保留对 trackLayer 的引用并将动画添加到该层。

class LoginDialogView: UIViewController {
    lazy var loaderView: UIView = {
        let loaderView = UIView()
        loaderView.backgroundColor = .yellow
        return loaderView
    }()

    var trackLayer: CAShapeLayer?

    ...
    ...
    ...

    private func setupCircleLayers() {
        trackLayer = createCircleShapeLayer(strokeColor: UIColor(red: 56/255,
                                                                 green: 25/255,
                                                                 blue: 49/255,
                                                                 alpha: 1),
                                            fillColor: #colorLiteral(red: 0.9686274529, green: 0.78039217, blue: 0.3450980484, alpha: 1))
        loaderView.layer.addSublayer(trackLayer!)
        startAnimating()
    }

    ...
    ...
    ...

    private func animateRing(){
        let rotationAnimation = CABasicAnimation(keyPath: "strokeEnd")
        rotationAnimation.fromValue = 0 * (CGFloat.pi / 180)
        rotationAnimation.toValue = 360 * (CGFloat.pi / 180)
        rotationAnimation.duration = 1.6
        rotationAnimation.repeatCount = HUGE
        trackLayer.add(rotationAnimation, forKey: "strokeEnd")
    }

    ...
    ...
    ...
}

注意:以上代码中的...指的是您代码的截断部分。