【发布时间】:2021-11-08 07:43:22
【问题描述】:
所以我正在尝试学习如何在 UIKit 中绘制圆圈,并且我已经大致了解了它们,但我只是在尝试实现另外一件事。在下面的视频中,当圆的尾部到达末端时,我希望尾部没有完全到达头部,这意味着我希望圆的大小不会完全缩小。
我在下面的视频中有它,但仍然有捕捉到尾巴消失并且动画从头部重新开始的片段。所以我希望尾巴的消失不要消失。
视频演示: https://github.com/DJSimonSays93/CircleAnimation/blob/main/README.md
代码如下:
class SpinningView: UIView {
let circleLayer = CAShapeLayer()
let rotationAnimation: CAAnimation = {
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0
animation.toValue = Double.pi * 2
animation.duration = 3 // increase this duration to slow down the circle animation effect
animation.repeatCount = MAXFLOAT
return animation
}()
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
func setup() {
circleLayer.lineWidth = 10.0
circleLayer.fillColor = nil
//circleLayer.strokeColor = UIColor(red: 0.8078, green: 0.2549, blue: 0.2392, alpha: 1.0).cgColor
circleLayer.strokeColor = UIColor.systemBlue.cgColor
circleLayer.lineCap = .round
layer.addSublayer(circleLayer)
updateAnimation()
}
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = min(bounds.width, bounds.height) / 2 - circleLayer.lineWidth / 2
let startAngle: CGFloat = -90.0
let endAngle: CGFloat = startAngle + 360.0
circleLayer.position = center
circleLayer.path = createCircle(startAngle: startAngle, endAngle: endAngle, radius: radius).cgPath
}
private func updateAnimation() {
//The strokeStartAnimation beginTime + duration value need to add up to the strokeAnimationGroup.duration value
let strokeStartAnimation: CABasicAnimation = CABasicAnimation(keyPath: "strokeStart")
strokeStartAnimation.beginTime = 0.5
strokeStartAnimation.fromValue = 0
strokeStartAnimation.toValue = 0.93 //change this to 0.93 for cool effect
strokeStartAnimation.duration = 3.0
strokeStartAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
let strokeEndAnimation: CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd")
strokeEndAnimation.fromValue = 0
strokeEndAnimation.toValue = 1.0
strokeEndAnimation.duration = 2.0
strokeEndAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
let colorAnimation = CABasicAnimation(keyPath: "strokeColor")
colorAnimation.fromValue = UIColor.systemBlue.cgColor
colorAnimation.toValue = UIColor.systemRed.cgColor
let strokeAnimationGroup: CAAnimationGroup = CAAnimationGroup()
strokeAnimationGroup.duration = 3.5
strokeAnimationGroup.repeatCount = Float.infinity
strokeAnimationGroup.fillMode = .forwards
strokeAnimationGroup.isRemovedOnCompletion = false
strokeAnimationGroup.animations = [strokeStartAnimation, strokeEndAnimation, colorAnimation]
circleLayer.add(strokeAnimationGroup, forKey: nil)
circleLayer.add(rotationAnimation, forKey: "rotation")
}
private func createCircle(startAngle: CGFloat, endAngle: CGFloat, radius: CGFloat) -> UIBezierPath {
return UIBezierPath(arcCenter: CGPoint.zero,
radius: radius,
startAngle: startAngle.toRadians(),
endAngle: endAngle.toRadians(),
clockwise: true)
}
【问题讨论】:
-
没有花很多时间查看代码,“想法”是开始和结束角度不完整(即不是 0 和 1),相反,你只让他们填满几乎所有的圆圈,比如从 0.1 到 0.9 什么的。这意味着你需要改变你的计算来弥补这一点,所以你只填充了 0.8% 的圆圈......从概念上讲
标签: ios swift xcode animation cashapelayer