【问题标题】:Connect two strokeEnd animations连接两个 strokeEnd 动画
【发布时间】:2016-11-28 19:15:30
【问题描述】:

我正在尝试制作一个类似于 Android 材料设计循环不确定活动指示器的自定义活动指示器。基本上我想画两次圆圈并擦除它,但擦除和绘制不会同时或速度发生。这是我目前所拥有的:

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 重新开始绘制。有没有人知道如何解决这个问题?

【问题讨论】:

  • 您的代码在我尝试编译时显示错误,请输入您的真实代码,以帮助您
  • @ReinierMelian 这是 Swift 3 代码,请确保您使用的是 Xcode 8 或将其转换为 Swift 2。@Banana,progressLayer 是什么?
  • progressLayerCAShapeLayer,我在上面的问题中添加了这个。
  • @Banana,你能不能把你想要什么和你实际得到什么发一个.gif,以便更容易理解这个问题

标签: ios swift animation core-animation swift3


【解决方案1】:

当第一个 strokeEnd 动画完成并且第二个动画开始时 有一种闪光,表示画出的圆圈部分 直到那个点消失,然后从 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 * duration) 的开头

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多