CAShapeLayer circle strokeEnd 没有连接到开始
CAShapeLayer circle strokeEnd not connecting to start
我正在创建一个类似于右侧 here Android material 设计加载指示器的圆圈,但该圆圈并未自行完成。
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 和转换动画的各种不同配置,但似乎没有任何效果。修改 strokeEnd toValue
动画不会改变任何东西。
圆周率是圆的二分之一。如果您删除旋转,并将其用作您的 basePath
:
basePath = UIBezierPath(arcCenter: view.center,
radius: 100,
startAngle: 0,
endAngle: 1.0 * CGFloat.pi,
clockwise: true).cgPath
该行将从 3:00 开始并转到 9:00
如果你从二分之一开始:
basePath = UIBezierPath(arcCenter: view.center,
radius: 100,
startAngle: CGFloat.pi / 2,
endAngle: 1.0 * CGFloat.pi,
clockwise: true).cgPath
你的行从 6:00 到 9:00
在endAngle上加一个半圆周角:
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
我正在创建一个类似于右侧 here Android material 设计加载指示器的圆圈,但该圆圈并未自行完成。
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 和转换动画的各种不同配置,但似乎没有任何效果。修改 strokeEnd toValue
动画不会改变任何东西。
圆周率是圆的二分之一。如果您删除旋转,并将其用作您的 basePath
:
basePath = UIBezierPath(arcCenter: view.center,
radius: 100,
startAngle: 0,
endAngle: 1.0 * CGFloat.pi,
clockwise: true).cgPath
该行将从 3:00 开始并转到 9:00
如果你从二分之一开始:
basePath = UIBezierPath(arcCenter: view.center,
radius: 100,
startAngle: CGFloat.pi / 2,
endAngle: 1.0 * CGFloat.pi,
clockwise: true).cgPath
你的行从 6:00 到 9:00
在endAngle上加一个半圆周角:
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