ios - 连接两个 strokeEnd 动画

标签 ios swift animation core-animation swift3

我正在尝试制作一个类似于 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.

如果比较 drawAnimationendDrawAnimation 的设置,您会发现除了 beginTime 属性外,它们是相同的。这就是导致你闪烁的原因。它们都从 0 开始,都以 1 结束。由于您没有指定所需的结果,我可以假设您希望 endDrawAnimationfromValue 为 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 上同时运行:

  • eraseAnimation0.2 开始,持续时间为 0.5 * duration
  • endEraseAnimation0.5 * duration 开始。

这意味着 eraseAnimation 的结束(0.2 + 0.5 * duration)总是大于 endEraseAnimation 的开始( 0.5 * 持续时间)

关于ios - 连接两个 strokeEnd 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38567867/

相关文章:

c# - 在 WPF 中显示动画 gif

jquery - 没有 .hide() 函数的淡入?

ios - UITableview委托(delegate)方法在json方法之前调用

ios - 嵌入式二进制文件的包标识符没有以父应用程序的包标识符为前缀

ios - 使用模式时将数据传递给 UIViewController

swift - var set to struct 修改时真的被替换了吗?

Java(2D)动画库

ios - 如何搜索特定半径内的位置?

ios - 无法识别的选择器发送到实例 NSTimer Swift

ios - 我想使用 didSelectRowAt 将数组从 UITableView 显示到下一个 viewController