2016-10-27 3 views
0

テーブルビューの再利用可能なセルにUISliderがあります。
値が変更されると、カスタムメソッドvalueChanged()が呼び出され、テーブルビューのreloadData()メソッドがトリガされます。 reloadData()cellForRowAtIndexPathが呼び出され、スライダが変更されたセルがロードされるとすぐに、ボタンがセルの右側からスライドしているかのように見える2つの拘束がアニメーション表示されます。

基本的に、私が作成しようとしている効果は、ユーザーがスライドを開始するとすぐにアニメーションが行われ、ボタンが表示されることです。
これはキャッチですが、UISliderisContiniousプロパティはtrueに設定されているため、アニメーションがすぐに実行され、ユーザーがスライダの指を離すまで遅れることはありません。しかし、isContiniousからtrueに設定すると、ユーザがコミットする小さなスライドごとにreloadData()(これは私のカスタムvalueChanged()の中にあった)が多くの時間と呼ばれるようになります。

いくつかの調査を行い、多くのデバッグ手法を試した結果、reloadData()が呼び出されるとすぐに、実行中のアニメーション(まだreloadData()のアニメーションが呼び出されている)が中断され、アニメーションが終了した後であるはずです。したがって、シナリオをリキャップする

1)スライダを移動、
2)valueChanged()
3、reloadData()をトリガ)アニメーション
4)reloadData()が直ちに再びステップで開始アニメーションを台無しに呼び出され、レイアウトを更新するために開始3.

isContinioustrueに設定されているとすべてが非常に速くなっているため、アニメーションは完了するまでに時間がかからず、reloadData()が再び呼び出されます。これにより、アニメーションが破棄され、UIView.animate(withDuration:)が呼び出され、正常に機能することがわかっていても、ボタンがアニメーションなしで画面に表示されているかのように見えます。 reloadData()を呼び出さずにテーブルをリフレッシュする方法があるのだろうかと思っていたので、基本的にこの方法の代わりに(私はすでにreloadCellAtIndexPathを試しましたが、これは全く同じ効果があります)。そうでない場合、アニメーションが他のレイアウト更新メソッドによって中断されずに終了することを絶対に確実にする方法はありますか?

答えて

0

リフレッシュによってアニメーションが終了する場合は、アニメーションの実行が終了するまでreloadRowsAtIndexPathsコールを延期することができます。通常、私はあなたのアニメーションブロックの補完ハンドラでそれを呼び出すと言いますが、変更された値が複数のアニメーションを発生させるかもしれないようです。代わりに、アニメーションを開始するときに、リロードを実行するブロックを実行するタイマーを開始します。新しいアニメーションを開始する場合は、古いタイマーを無効にして新しいタイマーを作成します。リロードは最終的なアニメーションが完了したときにのみ実行されます。

var timer = Timer() 

    func valueChanged() { 
     timer.invalidate() 
     timer = Timer.scheduledTimer(withTimeInterval: animationDuration, repeats: false) { _ in 
      //Call reload here 
     } 
     //Animate here 
    } 
+0

ありがとうございます!私はタイマーを使用して終了しませんでしたが、あなたはアニメーションブロックからタイマーをトリガーするアイデアは、ちょうどアニメーションがまだ実行されているかどうかをチェックするカスタムブール値を使用するという考えに私をもたらした。私はアニメーションが完了した後、UIViewのanimateWithDurationの完了ブロックが呼び出されたことを知らなかった。アニメーションが開始された直後に呼び出されたと思っていましたが、アニメーションがまだ実行中であるかどうかをコンプリートブロック内のブールパラメータが示していました。 –

+0

私はこれを理解した後、自分自身のisAnimating Booleanを作成するだけの簡単なことでした。アニメーションが開始されたときにtrueに設定され、アニメーションが完了した後に完了ブロックでfalseに設定された。私のvalueChangedメソッド(毎秒bazillion回呼び出される)では、isAnimatingがfalseに設定されているかどうかをチェックし、reloadData()コードがあればそれを実行します。魅力のように動作します。ですから、基本的には、animateWithDurationの完了ブロックの目的を誤解していたため、私はこの問題を、それよりもはるかに複雑にしました。 –