CAShapeLayer обводка круга Не завершается, чтобы начать - PullRequest
0 голосов
/ 02 апреля 2020

Я создаю круг, похожий на Android индикатор загрузки материала, показанный справа здесь , но круг не завершает себя.

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 * пи / 2, но я считаю, что штрих-конец некорректно останавливается на пи. Я пробовал различные конфигурации анимации strokeEnd и transform, но, похоже, ничего не получалось. Изменение анимации strokeEnd toValue ничего не меняет.

Gif of issue

1 Ответ

1 голос
/ 02 апреля 2020

PI - это половина круга. Если вы удалите вращение и используете его как basePath:

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

enter image description here

Линия начнется в 3:00 и go до 9: 00

Если вы начинаете с половины PI:

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

enter image description here

Ваша строка начинается с 6: От 00 до 9: 00

Добавьте половину PI к концу. Угол:

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

enter image description here

и вы получите 6:00 до 12:00, что составляет почти , что вы хотите.

Теперь вы добавляете вращение PI (помните, это половина полного круга):

enter image description here

и вы с 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

enter image description here

...