【问题标题】:CAShapeLayer circle strokeEnd not connecting to startCAShapeLayer 圆笔画结束未连接开始
【发布时间】:2020-04-02 14:18:07
【问题描述】:

我正在创建一个类似于右侧 here 上的 Android Material Design 加载指示器的圆圈,但该圆圈并未自行完成。

class ViewController: UIViewController {

    var baseLayer = CAShapeLayer()

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

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        animate()
    }

    private func setUp() {
        view.layer.addSublayer(baseLayer)
        let basePath = UIBezierPath(arcCenter: view.center,
                                    radius: 100,
                                    startAngle: CGFloat.pi / 2,
                                    endAngle: 2 * CGFloat.pi,
                                    clockwise: true).cgPath
        baseLayer.strokeColor = UIColor.gray.cgColor
        baseLayer.path = basePath
        baseLayer.fillColor = UIColor.clear.cgColor
        baseLayer.lineWidth = 2
        baseLayer.position = view.center
        baseLayer.strokeEnd = 0
    }

    private func animate() {
        CATransaction.begin()
        let strokeEndAnimation = CABasicAnimation(keyPath: "strokeEnd")
        strokeEndAnimation.toValue = 1
        strokeEndAnimation.fillMode = .forwards
        strokeEndAnimation.isRemovedOnCompletion = false
        strokeEndAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)

        let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotationAnimation.toValue = CGFloat.pi
        rotationAnimation.fillMode = .forwards
        rotationAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        rotationAnimation.isRemovedOnCompletion = false

        let group = CAAnimationGroup()
        group.duration = 1.5
        group.repeatCount = 0
        group.fillMode = .forwards
        group.isRemovedOnCompletion = false
        group.animations = [strokeEndAnimation, rotationAnimation]

        baseLayer.add(group, forKey: "animations")
        CATransaction.commit()
    }
}

下图显示了我在说什么。它正确地停在 3*pi/2 但我相信 strokeEnd 错误地停在 pi 处。我尝试了各种不同的 strokeEnd 和 transform 动画配置,但似乎没有任何效果。修改 strokeEnd toValue 动画不会改变任何东西。

【问题讨论】:

  • 我对你想要的最终结果有点困惑......你想要画一个完整的圆圈并且让整个事物旋转为正在画吗?
  • 如果你用全班更新你的问题(或者至少足够我们可以复制/粘贴并查看它),我们可以看看。只有部分代码很难提供帮助。
  • 疑难解答:您是否尝试过从组中删除旋转动画以确保 strokeEnd 动画按您编写的那样工作?
  • @Grady - 试试endAngle: 3 * CGFloat.pi(3 而不是 2)

标签: ios swift caanimation


【解决方案1】:

PI 是圆的二分之一。如果您删除旋转,并将其用作您的basePath

    basePath = UIBezierPath(arcCenter: view.center,
                            radius: 100,
                            startAngle: 0,
                            endAngle: 1.0 * CGFloat.pi,
                            clockwise: true).cgPath

线路从3:00开始,到9:00

如果你从 PI 的二分之一开始:

    basePath = UIBezierPath(arcCenter: view.center,
                            radius: 100,
                            startAngle: CGFloat.pi / 2,
                            endAngle: 1.0 * CGFloat.pi,
                            clockwise: true).cgPath

您的线路从 6:00 到 9:00

在 endAngle 中添加半个 PI:

    basePath = UIBezierPath(arcCenter: view.center,
                            radius: 100,
                            startAngle: CGFloat.pi / 2,
                            endAngle: 1.5 * CGFloat.pi,
                            clockwise: true).cgPath

你得到 6:00 到 12:00,这几乎是你想要的。

现在您添加 PI 的旋转(请记住,这是一个完整圆的一半):

你在 12:00 到 6:00。

要将结束时间拖到 12:00,必须添加另一个 PI

    var basePath = UIBezierPath(arcCenter: view.center,
                                radius: 100,
                                startAngle: CGFloat.pi / 2,
                                endAngle: 2.5 * CGFloat.pi,
                                clockwise: true).cgPath

【讨论】:

    猜你喜欢
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    相关资源
    最近更新 更多