Ios 检测UIScrollview已到达底部

Ios 检测UIScrollview已到达底部,ios,uiscrollview,Ios,Uiscrollview,我有一个带有图像的UIScrollView,当用户滚动到scrollview的末尾时,我想更新内容。这是我在到达scrollview底部时要检测的代码: 下面的代码在scrollViewDidScroll:delegate中实现 CGFloat scrollViewHeight = imagesScrollView.bounds.size.height; CGFloat scrollContentSizeHeight = imagesScrollView.contentSize.height;

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

下面的代码在
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,但它不起作用,而且函数也没有被调用。实现
scrollViewDidScroll:
并检查
contentOffset
中的
是否考虑添加布尔值。当第一次调用该方法时,或者当用户回滚时,更新该方法。

如果要在swift中检测它们:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{
    float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height) 
    {
        // we are at the end
    }
}
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
}}
覆盖函数scrollViewDidScroll(scrollView:UIScrollView){
if(scrollView.contentOffset.y>=(scrollView.contentSize.height-scrollView.frame.size.height)){
//触底
}
if(scrollView.contentOffset.y<0){
//到达顶端
}
if(scrollView.contentOffset.y>=0&&scrollView.contentOffset.y<(scrollView.contentSize.height-scrollView.frame.size.height)){
//不上不下
}}

有时您必须在条件中使用+1,因为contentSize.height会给您一些小数,因此如果您使用它,您可以避免使用它

override func scrollViewDidScroll(scrollView: UIScrollView) {

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

卡洛斯的答案更好

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

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) {
            //bottom reached
        }
    }
对于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
    }      
}

我对此采用了混合方法。让我解释一下:

虽然您的演算是正确的,但您所听的代理是一个过度的任务,因为
scrollViewDidScroll
被多次调用,这可能会导致性能问题。您应该(和我一样)使用
ScrollViewDiEndDraging
ScrollViewDiEndDecreating
,它们在各自的事件结束时只调用一次

func-scrollViewDiEndDraging(scrollView:UIScrollView,willDecreate-Decreate:Bool){
//手指抬起后,滚动加速没有继续
如果!减速{
末尾的executeActionAtTheEnd(of:scrollView)
}
}
func ScrollViewDiEndDecelling(scrollView:UIScrollView){
末尾的executeActionAtTheEnd(of:scrollView)
}
private func ExecuteActionAtthend(属于scrollView:UIScrollView){
如果scrollView.contentOffset.y+1>=(scrollView.contentSize.height-scrollView.frame.size.height){
//当到达滚动结束时,在此处执行任何您想要的操作
}
}

添加一个条件标志以过滤掉额外的调用,例如,如果(imagesView有子imagesBottomLoadingView)ok,这很简单,但我不这么认为。非常感谢。好啊请注意,您已经在
scrollViewDidScroll:
delegate中编写了代码,以避免任何混淆如果视图最初加载,“到达底部”部分也是正确的。正如@Proveme007所指出的,使用
ScrollViewDiEndDeclaring
方法可以避免这种情况。此外,使用这种方法,不需要处理额外的标志。您应该围绕您的答案进行一些解释。问题是,当你使用内容插页和/或调整后的插页时,这不起作用,这在使用iPhoneX及其安全区域时是正常的。