检测 UIScrollview 底部到达

Posted

技术标签:

【中文标题】检测 UIScrollview 底部到达【英文标题】:Detect UIScrollview bottom reached 【发布时间】:2013-12-14 13:26:41 【问题描述】:

我有一个带有图像的 UIScrollView,当用户滚动到滚动视图的末尾时,我想更新内容。这是我检测何时到达滚动视图底部的代码:

下面的代码在scrollViewDidScroll:delegate中实现

CGFloat scrollViewHeight = imagesScrollView.bounds.size.height;
CGFloat scrollContentSizeHeight = imagesScrollView.contentSize.height;
CGFloat bottomInset = imagesScrollView.contentInset.bottom;
CGFloat scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight;

if(imagesScrollView.contentOffset.y > scrollViewBottomOffset)


    [imagesView addSubview:imagesBottomLoadingView];

    [self downloadImages];


我的问题是当用户滚动到底部时,我的函数被调用了几次,但我只想调用一次。我尝试使用 imagesScrollView.contentOffset.y == scrollViewBottomOffset 但它不起作用并且没有调用该函数

【问题讨论】:

添加条件标志以过滤掉多余的调用,例如 if (imagesView has child imagesBottomLoadingView) 好的,这很容易,但我没想到。谢谢! 【参考方案1】:

如果你想快速检测它们:

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

【讨论】:

如果视图最初加载,“到达底部”部分也是如此。正如@Proveme007 指出的那样,使用scrollViewDidEndDeceleratingmethod 可以避免这种情况。此外,使用这种方法不需要处理额外的标志。【参考方案2】:

卡洛斯的答案更好。

对于 Swift 4.x,您必须更改方法名称:

func scrollViewDidScroll(_ scrollView: UIScrollView) 
        if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) 
            //bottom reached
        
    

【讨论】:

【参考方案3】:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 

    float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height) 
    
        // we are at the end
    

【讨论】:

【参考方案4】:

有时您必须在条件中使用 +1,因为 contentSize.height 会给您小数点后几位,所以如果您使用它,请避免使用它...

override func scrollViewDidScroll(scrollView: UIScrollView) 

   if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) 
       //bottom reached
   

【讨论】:

【参考方案5】:

你有没有想过添加一个布尔值。在第一次调用该方法时更新它,并且可能在用户向上滚动时更新它。

【讨论】:

【参考方案6】:

我为此使用了混合方法。让我解释一下:

虽然您的微积分是正确的,但您收听的委托是多余的,因为 scrollViewDidScroll 被多次调用,这可能会导致性能问题。你应该(和我一样)使用scrollViewDidEndDraggingscrollViewDidEndDecelerating,它们在各自的事件结束时只调用一次。

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) 
    // Scrolling acceleration didn't continue after the finger was lifted
    if !decelerate 
        executeActionAtTheEnd(of: scrollView)
    


func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 
    executeActionAtTheEnd(of: scrollView)


private func executeActionAtTheEnd(of scrollView: UIScrollView) 
    if scrollView.contentOffset.y + 1 >= (scrollView.contentSize.height - scrollView.frame.size.height) 
        // Do here whatever you want when end of scrolling is reached
    

【讨论】:

【参考方案7】:

实现scrollViewDidScroll: 并检查contentOffset 是否到达终点

【讨论】:

好的...请提及您已在scrollViewDidScroll:delegate 中编写代码以避免任何混淆【参考方案8】:

对于 Swift 4.5:

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    
   let scrollViewHeight = scrollView.frame.size.height
    let scrollContentSizeHeight = scrollView.contentSize.height
     let scrollOffset = scrollView.contentOffset.y

    if (scrollOffset == 0)
    
        // then we are at the top
        print("then we are at the top")
    
    else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
    
        print("then we are at the end")
        // then we are at the end
          

【讨论】:

你应该用一些解释来围绕你的答案。那真的会提高它的质量。 问题是,当您使用内容插入和/或调整后的插入时,这不起作用,这在使用 iphone x 及其安全区域时是正常的。

以上是关于检测 UIScrollview 底部到达的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView,到达滚动视图的底部

scrollViewDidScroll(_ scrollView: UIScrollView) 到达底部后如何保持 UIButton 浮动?

UIScrollView 仅检测底部的滑动

如何在 iOS 中检测 UITextView (UIScrollView) 故障的底部

UIScrollView 切断底部内容

iPhone - 知道UIScrollView是否达到顶部或底部