我正在尝试制作一个类似于 Android Material 设计循环不确定事件指示器的自定义事件指示器。基本上我想画圆圈两次并删除它,但删除和绘制不会同时或速度发生。这是我目前所拥有的:
let progressLayer = CAShapeLayer()
progressLayer.strokeColor = UIColor.red().cgColor
progressLayer.fillColor = nil
progressLayer.lineWidth = 2
let drawAnimation = CABasicAnimation(keyPath: "strokeEnd")
drawAnimation.duration = duration / 2
drawAnimation.fromValue = 0
drawAnimation.toValue = 1
drawAnimation.isRemovedOnCompletion = false
drawAnimation.fillMode = kCAFillModeForwards
let eraseAnimation = CABasicAnimation(keyPath: "strokeStart")
eraseAnimation.duration = duration / 2
eraseAnimation.beginTime = 0.2
eraseAnimation.fromValue = 0
eraseAnimation.toValue = 0.4
eraseAnimation.isRemovedOnCompletion = false
eraseAnimation.fillMode = kCAFillModeForwards
let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd")
endDrawAnimation.beginTime = duration / 2
endDrawAnimation.duration = duration / 2
endDrawAnimation.fromValue = 0
endDrawAnimation.toValue = 1
endDrawAnimation.isRemovedOnCompletion = false
endDrawAnimation.fillMode = kCAFillModeForwards
let endEraseAnimation = CABasicAnimation(keyPath: "strokeStart")
endEraseAnimation.beginTime = duration / 2
endEraseAnimation.duration = duration / 4
endEraseAnimation.fromValue = 0.4
endEraseAnimation.toValue = 1
endEraseAnimation.isRemovedOnCompletion = false
endEraseAnimation.fillMode = kCAFillModeForwards
let endEraseAnimation2 = CABasicAnimation(keyPath: "strokeStart")
endEraseAnimation2.beginTime = duration * 3 / 4
endEraseAnimation2.duration = duration / 4
endEraseAnimation2.fromValue = 0
endEraseAnimation2.toValue = 1
endEraseAnimation2.isRemovedOnCompletion = false
endEraseAnimation2.fillMode = kCAFillModeForwards
let animations = CAAnimationGroup()
animations.duration = duration
animations.animations = [drawAnimation, eraseAnimation, endDrawAnimation, endEraseAnimation, endEraseAnimation2]
animations.isRemovedOnCompletion = false
animations.fillMode = kCAFillModeForwards
progressLayer.add(animations, forKey: "stroke")
除一个问题外,代码按预期执行所有操作。当第一个 strokeEnd
动画完成并且第二个动画开始时,会有一种闪光,这意味着绘制到该点消失的圆圈部分然后从 0 重新开始绘制。有没有人有任何想法如何解决这个问题?
最佳答案
When the first strokeEnd animation is done and the second one starts there is sort of a flash meaning the part of the circle that was drawn till that point disappears and then drawing starts again from 0.
如果比较 drawAnimation
和 endDrawAnimation
的设置,您会发现除了 beginTime
属性外,它们是相同的。这就是导致你闪烁的原因。它们都从 0 开始,都以 1 结束。由于您没有指定所需的结果,我可以假设您希望 endDrawAnimation
的 fromValue
为 1。
let drawAnimation = CABasicAnimation(keyPath: "strokeEnd")
drawAnimation.duration = duration / 2
drawAnimation.fromValue = 0
drawAnimation.toValue = 1
drawAnimation.isRemovedOnCompletion = false
drawAnimation.fillMode = kCAFillModeForwards
let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd")
endDrawAnimation.beginTime = duration / 2 // Starts after the first animation and starts with 0 again.
endDrawAnimation.duration = duration / 2
endDrawAnimation.fromValue = 0
endDrawAnimation.toValue = 1
endDrawAnimation.isRemovedOnCompletion = false
endDrawAnimation.fillMode = kCAFillModeForwards
改进建议
据我所知,您想要创建关键帧动画,这意味着您已经预定义了动画行为(速度、值等)发生变化的偏移量。您可能需要考虑使用 CAKeyframeAnimation
反而。
我不确定您是否知道这一点,但目前您有两个动画在 strokeStart
上同时运行:
eraseAnimation
从0.2
开始,持续时间为0.5 * duration
endEraseAnimation
从0.5 * duration
开始。
这意味着 eraseAnimation
的结束(0.2 + 0.5 * duration
)总是大于 endEraseAnimation
的开始( 0.5 * 持续时间
)
关于ios - 连接两个 strokeEnd 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38567867/