2017-03-08 92 views
0

我想要当用户拖动一个UIView,当用户释放拖动的褪回创造一个双线淡出的动画。
因此,我有两个功能undrawLines(称为泛姿态开始)和redrawLines(称为泛手势结束),这是由我的UIPanGestureRecognizer操作处理程序调用。CAShapeLayer奇怪的动画行为

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
这里是一个演示中,第一部分说明应该如何,第二个显示错误:

enter image description here

回答

1

我相信在这里你的问题是一个竞争条件与完成处理:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { 
    mill.line1.removeFromSuperlayer() 
    mill.line2.removeFromSuperlayer() 
}) 

如果您的用户发布,因此redrawLines 0.3秒超时之前被调用,这仍然被调用和删除线。

你可能想保持状态标志,指示当前的意图,然后检查它的异步回调:

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") 
} 

你显然需要实例VAR linesHidden此添加到类工作也:)

+0

完美,谢谢你是它! – Codey