2016-11-30 14 views
0

次のブロックは自分のコードです。私は理由はわかりませんが、アニメーションの遅延はまったく機能していません。何秒にもかかわらず、私はそれを増やす。アニメーションが正しく機能しない(Swift 3)

func changeLabelisTapped(_ textLabel: UILabel, tapGesture: UITapGestureRecognizer) { 
    for i in 0...2{ 
     UIView.animate(withDuration: 2, delay: Double(i)+2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
      self.subArray.remove(at: 0) 
      self.collectionView.deleteItems(at: [IndexPath(row: 0, section: 0)]) 
     }), completion: nil) 
    } 
    let tempArray = Array(self.tabledData[3...self.tabledData.count-1]) 
    print(tempArray.count) 
    for j in 0...2{ 
     UIView.animate(withDuration: 2, delay: 2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
      let newElement = tempArray[j] 
      self.subArray.append(newElement) 
      self.collectionView.insertItems(at:[IndexPath(row: j, section: 0)]) 
     }), completion: nil) 
    } 
} 

答えて

1

UIViewのアニメーションがキューに入れられない。だから毎回あなたがループを通ってそれを処理すると、次のアニメーションは前のアニメーションをキャンセルし、あなたは遅延を見ません。ループを使用する代わりに、アニメーションをチェーンして、次のアニメーションが完了ハンドラで呼び出されるようにする必要があります。ループを削除して、完了ハンドラ内で次のアニメーションを呼び出すようにします。

var currentCount = 0 

    UIView.animate(withDuration: 2, delay: 2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
     let newElement = tempArray[self.currentCount] 
     self.subArray.append(newElement) 
     self.collectionView.insertItems(at:[IndexPath(row: self.currentCount, section: 0)]) 
    }), completion: { _ in 
     //next animation follows here 
     self.currentCount += 1 
     UIView.animate(withDuration: 2, delay: 2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
     let newElement = tempArray[self.currentCount] 
     self.subArray.append(newElement) 
     self.collectionView.insertItems(at:[IndexPath(row: self.currentCount, section: 0)]) 
    }), completion: { _ in //and so on 

    }) 

    }) 

あなたはきれいにアニメーションが起こるはず回数を制御したい場合は、完了ハンドラ内で再帰的コールバックを使用することができます。これを行うには、アニメーションコードを関数に移動します。誰を助けるかもしれない期待どおりに動作しない場合

let loopCount = 3 

    var currentCount = 0 

    func animateMyLabel() { 
    UIView.animate(withDuration: 2, delay: 2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
     let newElement = tempArray[self.currentCount] 
     self.subArray.append(newElement) 
     self.collectionView.insertItems(at:[IndexPath(row: self.currentCount, section: 0)]) 
    }), completion: { _ in 
     if self.currentCount < self.loopCount { 
      self.currentCount += 1 
      //call the animation again 
      self.animateMyLabel() 
     } 

    }) 

    } 

EDIT

私がやっている現在のプロジェクトで同様の遅延の問題に直面した、私は遅延を強制する新しい方法を学んだことこの質問に遭遇する。解決方法は、delay(seconds:n){}を追加することによって、次のアニメーションが発生する直前に完了ハンドラの遅延を強制することです。ここで、nは遅延が発生する秒数です。だから、問題にこれを追加します。

let loopCount = 3 

    var currentCount = 0 

    func animateMyLabel() { 
    UIView.animate(withDuration: 2, delay: 2, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: ({ 
     let newElement = tempArray[self.currentCount] 
     self.subArray.append(newElement) 
     self.collectionView.insertItems(at:[IndexPath(row: self.currentCount, section: 0)]) 
    }), completion: { _ in 
     if self.currentCount < self.loopCount { 
      //add the delay here 
      delay(seconds: 2) { 
      self.currentCount += 1 
      //call the animation again 
      self.animateMyLabel() 
      } 
     } 

    }) 

    } 

をさらに、アニメーションがキューませんが、アニメーションのためのシーケンス内の次のアニメーションが前のアニメーションが完了することを可能にする遅延を持って設けられたループを使用することが可能です。

+0

まだ動作しません。遅延を10秒に増やしました。アニメーションの終了までに同じ時間がかかります。しかし、お返事いただきありがとうございます! – user3608914

+0

forループを削除してもまだ動作しません。 – gwinyai

+0

うん、私はあなたの2番目のブロックを試みた..それは動作しません... :(..私はアニメーションのチュートリアルを見た...ビデオは、あなたが遅れを増やす完了ボックスを必要としていないことを示しています.. delayCounterを増やす必要があり、それに応じてセルがレイアウトされます。つまり、挿入と削除のセルの問題かどうかわかりません。 – user3608914