检查 UIScrollView 是到达顶部还是底部

Check if a UIScrollView reached the top or bottom

提问人:Duck 提问时间:10/10/2011 最后编辑:pkambDuck 更新时间:10/20/2021 访问量:66374

问:

有没有办法知道 a 是否已到达顶部或底部?可能在方法中:UIScrollView

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView 
                  willDecelerate:(BOOL)decelerate
iOS Objective-C iPhone UISscrollView UISvLvViewDelegate

评论


答:

201赞 Luke 10/10/2011 #1

在类中实现 ,然后添加以下内容: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 值来进行修补。

评论

5赞 Wayne 1/10/2014
如果你在 中,你可能想做一些类似的事情: 和navigationControllerscrollOffset <= (0 - self.navigationController.navigationBar.frame.size.height - 20)(scrollOffset + scrollHeight) >= scrollContentSizeHeight
0赞 denikov 8/30/2014
问题是反弹......一旦到达顶部或底部,一切都会被调用两次。除了关闭表格或集合视图跳出之外,还有其他解决方案吗?
0赞 famfamfam 3/2/2021
如果 scrollview 顶部约束 != 0,则 scrollOffset 可能为 <0
89赞 Alexander Dvornikov 2/7/2013 #2

好吧,当您尝试确定 scrollView 是在顶部还是在底部时,也会参与其中。您可能还对 scrollView 位于顶部上方和底部下方的情况感兴趣。 这是我用来查找顶部和底部位置的代码:contentInsets

迅速:

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

评论

4赞 chadbag 5/18/2017
由于浮点数学的变幻莫测,我得到的“verticalOffsetForBottom”是 1879.05xxx,而我的 contentOffset.y 在 Swift 3 中处于底部时是 1879。所以我改成了return scrollViewBottomOffsetreturn scrollViewBottomOffset.rounded()
1赞 InkGolem 7/4/2018
从iOS 11开始,也将其考虑在内。safeAreaInsetsscrollView.contentOffset.y + scrollView.bounds.height - scrollView.safeAreaInsets.bottom
2赞 nemissm 2/17/2022
在 iOS 11 及更高版本中,您可能需要使用 代替 .adjustedContentInsetcontentInset
5赞 JPN 4/15/2014 #3

我确切地想出了该怎么做:

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!
}
42赞 ytbryan 10/1/2014 #4

如果你想要 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
    }
}
13赞 Rudolf Adamkovič 11/6/2015 #5

简单干净的扩展:

import UIKit

extension UIScrollView {

    var scrolledToTop: Bool {
        let topEdge = 0 - contentInset.top
        return contentOffset.y <= topEdge
    }

    var scrolledToBottom: Bool {
        let bottomEdge = contentSize.height + contentInset.bottom - bounds.height
        return contentOffset.y >= bottomEdge
    }

}

在 GitHub 上:

https://github.com/salutis/swift-scroll-view-edges

0赞 Radu Ghitescu 9/12/2018 #6

这样做(对于 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
        }


    }
}

评论

0赞 Joel 9/12/2018
欢迎来到 SO!在答案中发布代码时,解释代码如何解决 OP 的问题:)