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


Answers:


198

UIScrollViewDelegate在您的课程中实现,然后添加以下内容:

-(void)scrollViewDidScroll: (UIScrollView*)scrollView
{
    float scrollViewHeight = scrollView.frame.size.height;
    float scrollContentSizeHeight = scrollView.contentSize.height;
    float scrollOffset = scrollView.contentOffset.y;

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

希望这就是你所追求的!否则,可以通过在上面的代码中添加更多条件来改变条件,并将NSLog的值设为scrollOffset。


4
如果您使用的是navigationController,则可能需要执行以下操作:scrollOffset <= (0 - self.navigationController.navigationBar.frame.size.height - 20)(scrollOffset + scrollHeight) >= scrollContentSizeHeight
Wayne

问题在于弹跳……一旦到达顶部或底部,一切都会被调用两次。除了关闭表格或集合视图反弹以外,还有解决方案吗?
denikov

@denikov您是否找到任何解决方案?
2015年

83

好吧,contentInsets当您尝试确定scrollView是在顶部还是底部时,也会涉及到。您可能也有兴趣的情况下,当你滚动视图是上方的顶部和下方的底部。这是我用来查找顶部和底部位置的代码:

迅速:

extension UIScrollView {

    var isAtTop: Bool {
        return contentOffset.y <= verticalOffsetForTop
    }

    var isAtBottom: Bool {
        return contentOffset.y >= verticalOffsetForBottom
    }

    var verticalOffsetForTop: CGFloat {
        let topInset = contentInset.top
        return -topInset
    }

    var verticalOffsetForBottom: CGFloat {
        let scrollViewHeight = bounds.height
        let scrollContentSizeHeight = contentSize.height
        let bottomInset = contentInset.bottom
        let scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight
        return scrollViewBottomOffset
    }

}

目标C:

@implementation UIScrollView (Additions)

- (BOOL)isAtTop {
    return (self.contentOffset.y <= [self verticalOffsetForTop]);
}

- (BOOL)isAtBottom {
    return (self.contentOffset.y >= [self verticalOffsetForBottom]);
}

- (CGFloat)verticalOffsetForTop {
    CGFloat topInset = self.contentInset.top;
    return -topInset;
}

- (CGFloat)verticalOffsetForBottom {
    CGFloat scrollViewHeight = self.bounds.size.height;
    CGFloat scrollContentSizeHeight = self.contentSize.height;
    CGFloat bottomInset = self.contentInset.bottom;
    CGFloat scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight;
    return scrollViewBottomOffset;
}


@end

这个很好的答案,实现scrollviewdidscroll对性能不利
Vassily

3
如果不使用scrollViewDidScroll,该如何命名?
Dave G

2
由于浮点运算的变幻莫测的,我得到一个“verticalOffsetForBottom”的1879.05xxx和我contentOffset.y是1879年时在斯威夫特3.所以,我的底部变return scrollViewBottomOffsetreturn scrollViewBottomOffset.rounded()
chadbag

1
从iOS 11safeAreaInsets开始,它也纳入其中。scrollView.contentOffset.y + scrollView.bounds.height - scrollView.safeAreaInsets.bottom
InkGolem '18年

35

如果您想要快速编写代码:

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
    }
}


4

我想出了确切的方法:

CGFloat maxPosition = scrollView.contentInset.top + scrollView.contentSize.height + scrollView.contentInset.bottom - scrollView.bounds.size.height;
CGFloat currentPosition = scrollView.contentOffset.y + self.topLayoutGuide.length;

if (currentPosition == maxPosition) {
  // you're at the bottom!
}

0

这样做(对于Swift 3):

class MyClass: UIScrollViewDelegate {

   func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
           //scrolled to top, do smth
        }


    }
}

欢迎来到SO!在您的答案中发布代码时,有助于说明您的代码如何解决OP的问题:)
Joel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.