我正在尝试创建一个动画,其中当用户拖动UIView时两条线淡出并在用户释放拖动时淡入淡出。
因此,我有两个函数undrawLines
(在平移手势启动时调用)和redrawLines
(在平移手势结束时调用),由我的UIPanGestureRecognizer
动作处理程序调用。
func undrawLines() {
line1.opacity = 0.0
line2.opacity = 0.0
line1.removeAllAnimations()
line2.removeAllAnimations()
let opacityLine = CABasicAnimation(keyPath: "opacity")
opacityLine.fromValue = 1.0
opacityLine.toValue = 0.0
opacityLine.duration = 0.15
line1.add(opacityLine, forKey: "disappearLine1")
line2.add(opacityLine, forKey: "disappearLine2")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
mill.line1.removeFromSuperlayer()
mill.line2.removeFromSuperlayer()
})
}
func redrawLines() {
line1.opacity = 1.0
line2.opacity = 1.0
print("redraw")
line1.removeAllAnimations()
line2.removeAllAnimations()
self.layer.addSublayer(line1)
self.layer.addSublayer(line2)
let opacityLine = CABasicAnimation(keyPath: "opacity")
opacityLine.fromValue = 0.0
opacityLine.toValue = 1.0
opacityLine.duration = 0.15
line1.add(opacityMill, forKey: "appearLine1")
line2.add(opacityMill, forKey: "appearLine2")
}
问题是当redrawLines
动画仍在运行时调用undrawLines
时,这些行会显示奇怪的行为,不透明度为0。
这是一个演示,第一部分展示它应该如何,第二部分显示错误:
答案 0 :(得分:1)
我相信你的问题是你的完成处理程序的竞争条件:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
mill.line1.removeFromSuperlayer()
mill.line2.removeFromSuperlayer()
})
如果您的用户发布,因此{0.3}在0.3秒超时之前被调用,则仍然会调用它并删除这些行。
您可能希望保留一个指示当前意图的状态标志,然后在异步回调中检查它:
redrawLines
您显然需要将实例var func undrawLines() {
self.linesHidden = true // update state
line1.opacity = 0.0
line2.opacity = 0.0
line1.removeAllAnimations()
line2.removeAllAnimations()
let opacityLine = CABasicAnimation(keyPath: "opacity")
opacityLine.fromValue = 1.0
opacityLine.toValue = 0.0
opacityLine.duration = 0.15
line1.add(opacityLine, forKey: "disappearLine1")
line2.add(opacityLine, forKey: "disappearLine2")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in
if self?.linesHidden == true { // check this is still what we want to do
mill.line1.removeFromSuperlayer()
mill.line2.removeFromSuperlayer()
}
})
}
func redrawLines() {
self.linesHidden = false // update state
line1.opacity = 1.0
line2.opacity = 1.0
print("redraw")
line1.removeAllAnimations()
line2.removeAllAnimations()
self.layer.addSublayer(line1)
self.layer.addSublayer(line2)
let opacityLine = CABasicAnimation(keyPath: "opacity")
opacityLine.fromValue = 0.0
opacityLine.toValue = 1.0
opacityLine.duration = 0.15
line1.add(opacityMill, forKey: "appearLine1")
line2.add(opacityMill, forKey: "appearLine2")
}
添加到类中以使其工作:)