減速後のUIScrollViewでの静止オフセットの予測
-
22-07-2019 - |
質問
フリックジェスチャの後、UIScrollView内の最終的な静止オフセットを予測できるようにしたいと思います。ピクセル精度である必要はありませんが、ユーザーが違いを知覚しないように十分に近い(つまり、従来よりも過度に小さくも大きくも移動しない)。
誰かが尋ねるのは知っているので、なぜですか? UIScrollView内にテーブルビューのようなメニューコントロールがあります。一番上のメニュー項目が完全に表示され、UIScrollViewの上部にフラッシュされるようにします。 UIScrollViewのページング機能は、私が望んでいるものとはまったく異なります。強力なフリックは、ビューの境界の倍数を超えて飛ぶことがないからです。
通常のタッチイベントの処理は簡単です。 touchesEnded:withEvent:
では、最も近い完全なメニュー項目までスクロールできます。難しい部分は減速です。
減速率には、 UIScrollViewDecelerationRateNormal
と UIScrollViewDecelerationRateFast
の2つの定数があります。それらの値は、iPhone OS 3.0では0.998と0.990です。 Appleが動きを遅くするために使用する数学を解明しようとしましたが、空っぽになりました。
最終静止オフセットをある程度正確に予測できる場合は、減速の早い段階で scrollRectToVisible:animated:
を使用して、メニュー項目がビューの上部にあるオフセットに移動します境界。
数学に傾倒している人は、減速中にAppleが何をしているのか知っていますか?多数の減速イベントを収集し、それらをグラフ化し、何か近いものを考え出す必要がありますか?
解決
iOS 5でUIScrollViewのtargetContentOffsetを制御
iOS5 UIScrollViewDelegate
には新しいメソッドがあります: scrollViewWillEndDragging:withVelocity:targetContentOffset:
。
これは、あなたがやりたいことと完全に適合します。
このメソッドは、スクロールビューの値が pagingEnabledプロパティはYESです。アプリケーションは値を変更できます スクロールビューの場所を調整するtargetContentOffsetパラメーターの スクロールアニメーションを終了します。
iOS4以前の代替ソリューション
UIScrollView
を変更しますa>の decelerationRate
から UIScrollViewDecelerationFast
および scrollViewDidEndDecelerating
一番近い「ページ」に移動します。
高速減速により、完全に停止/スライドが少し自然になり、不快感が少なくなります。
他のヒント
UIScrollViewの減速中にスクロールの速度を確認し、速度が特定の値を下回ると、最も近いメニュー項目にスナップします。
UIScrollViewDelegate
メソッド scrollViewDidEndDragging:willDecelerate:
および scrollViewDidScroll:
。ユーザーが指を離してスクロールジェスチャを終了すると、 scrollViewDidEndDragging:willDecelerate:
が呼び出されます。 scrollViewDidScroll:
イベントの監視を開始し、 UIScrollView
の現在の位置とその前の位置との時間差を時間差で割った差を監視します:
float velocity = (currentPosition - lastPosition) / (currentTime - lastTime);
速度が最小値を下回ると、 UIScrollView
で scrollRectToVisible:animated:
を呼び出します。
コメントできない(50 repが必要だと思う)ので、これは完全な答えではありませんが、減速の0.998および0.990の値を考えると、私の直感では、現在の速度に各フレームの減速率を掛けるだけです。