web-dev-qa-db-ja.com

UIScrollView、スクロールビューの下部に到達

Appleドキュメントには次のデリゲートメソッドがあります:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt

ただし、必ずしも最下位にいるわけではありません。原因は、指を使って少しスクロールしてから減速すると、実際にはスクロールビューの一番下にいるわけではなく、まだ呼び出されているためです。基本的に、スクロールビューにさらにデータがあることを矢印で示し、下部に移動すると(バウンスするときなど)消えます。ありがとう。

37
Crystal

あなたができることは、あなたのcontentOffsetポイントがcontentSizeの下部にあることを確認することだと思います。だからあなたはおそらく次のようなことをすることができます:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height) {
        // we are at the end
    }
}

また、ユーザーが上にスクロールしたときにインジケーターを表示するためのネガティブなケースも必要になるでしょう。また、それにパディングを追加することもできます。たとえば、ユーザーが一番下ではなく、一番下にいるときにインジケーターを非表示にすることができます。

100
bensnider

Swiftで必要な場合は、次のようにします。

override func scrollViewDidScroll(scrollView: UIScrollView) {

    if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
        //reach bottom
    }

    if (scrollView.contentOffset.y < 0){
        //reach top
    }

    if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y < (scrollView.contentSize.height - scrollView.frame.size.height)){
        //not top and not bottom
    }
}
17
ytbryan

@bensniderの答えは正しいと思うが、exartではない。これら二つの理由のため

_1. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{}
_

if (bottomEdge >= scrollView.contentSize.height)をチェックすると、このメソッドは継続的に呼び出します

2。この中で_==_チェックを選択すると、この条件も2回有効になります。

  • (i)スクロールビューの最後が下端に触れたときに上にスクロールする場合
  • (ii)scrollviewが跳ね返り、自身の位置を保持する場合

これはより正確だと思う

この条件が2回有効であるケースはほとんどありません。しかし、ユーザーはこれに出くわすことはありません。

_- (void)scrollViewDidScroll:(UIScrollView *)scrollView
 {
    if (scrollView.contentOffset.y == roundf(scrollView.contentSize.height-scrollView.frame.size.height)) {
    NSLog(@"we are at the endddd");

   //Call your function here...

    }
}
_
14
umakanta

受け入れられた答えは、ボトムcontentInset値が負でない場合にのみ機能します。符号に関係なく、わずかな進化によりcontentInsetの下部が考慮されます。

CGFloat bottomInset = scrollView.contentInset.bottom;
CGFloat bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height - bottomInset;
if (bottomEdge == scrollView.contentSize.height) {
    // Scroll view is scrolled to bottom
}
9
kadam

実際には、@ bensniderのコードをscrollViewDidScrollに配置するだけでなく、このコード(Swift 3)で記述)の方がパフォーマンス面で優れています。

func scrollViewDidEndDragging(_ scrollView: UIScrollView,
                              willDecelerate decelerate: Bool) {
    if !decelerate {
        checkHasScrolledToBottom()
    }
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    checkHasScrolledToBottom()
}

func checkHasScrolledToBottom() {
    let bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height
    if bottomEdge >= scrollView.contentSize.height {
        // we are at the end
    }
}
3
Ivan

Swift 3

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.y == (scrollView.contentSize.height - scrollView.frame.size.height) {
        loadMore()
    }
}
2
Zhanserik

indexPathsForVisibleRowsのようなものを使用してUIViewに現在表示されているアイテムを確認し、モデルに表示されているよりも多くのアイテムがある場合は、下部に矢印を配置します。

0
Abizern