2017-03-08 5 views
0

ユーザーがUIViewをドラッグしたときに2つの線がフェードアウトし、ユーザーがドラッグを解除したときにフェードアウトするアニメーションを作成しようとしています。
したがって、私はUIPanGestureRecognizerアクションハンドラによって呼び出されるundrawLines(パンジェスチャ開始と呼ばれる)とredrawLines(パンジェスチャ終了と呼ばれる)の2つの機能を持っています。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") 
} 

問題はundrawLinesアニメーションがまだ実行されている間redrawLinesが呼び出されたときに、行が奇妙な行動と不透明度を示すことであることはここでは0
でのデモで、最初の部分は、それがどうあるべきかを示し、もう一つは、バグを示しています

enter image description here

答えて

1

私はここにあなたの問題は、あなたの完了ハンドラとの競合状態であると信じて:

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

ユーザーが解放してから0.3秒のタイムアウト前にredrawLinesが呼び出されると、これはまだ呼び出されて行を削除します。

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