私が取得したいのは、このスクロール ビューと同じ動作です。
これがネイティブ API ではなく HTML を使用していることはわかっていますが、UIKit コンポーネントとして実装しようとしています。
今、私が探している動作に:
- これはページ付きスクロール ビューですが、「ページ サイズ」はビューの幅よりも小さいことに注意してください。
- 左から右にスクロールすると、各ページが一番左の項目に「スナップ」します。
- 右端から左にスクロールすると、一番右の項目に「スナップ」します。
同じページですが、右から左:
私が試したこと:
- スクロール ビューをスーパー ビューよりも小さくして、hitTest をオーバーライドしようとしたところ、左から右への動作になりました。
- scrollViewWillEndDragging:withVelocity:targetContentOffset: を実装して、必要な targetContentOffset を設定しようとしましたが、速度を変更できないため、スクロールが遅すぎたり速すぎたりします。
- scrollViewDidEndDecelerating: を実装してから、正しいオフセットにアニメーション化しようとしましたが、スクロール ビューが最初に停止してから移動し、自然に見えません。
- scrollViewDidEndDragging:willDecelerate: を実装してから、正しいオフセットにアニメーション化しようとしましたが、スクロール ビューが「ジャンプ」して正しくアニメーション化されません。
私はアイデアがありません。
ありがとう!
アップデート:
最終的に Rob Mayoff の方法を使用しましたが、きれいに見えます。ユーザーが指をドラッグ、停止、離したときなど、速度が 0 のときに機能するように変更しました。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(CGPoint *)targetContentOffset {
CGFloat maxOffset = scrollView.contentSize.width - scrollView.bounds.size.width;
CGFloat minOffset = 0;
if (velocity.x == 0) {
CGFloat targetX = MAX(minOffset,MIN(maxOffset, targetContentOffset->x));
CGFloat diff = targetX - baseOffset;
if (ABS(diff) > offsetStep/2) {
if (diff > 0) {
//going left
baseOffset = MIN(maxOffset, baseOffset + offsetStep);
} else {
//going right
baseOffset = MAX(minOffset, baseOffset - offsetStep);
}
}
} else {
if (velocity.x > 0) {
baseOffset = MIN(maxOffset, baseOffset + offsetStep);
} else {
baseOffset = MAX(minOffset, baseOffset - offsetStep);
}
}
targetContentOffset->x = baseOffset;
}
このソリューションの唯一の問題は、スクロール ビューをスワイプしても「バウンス」効果が発生しないことです。「くっついた」感じです。