Check if a UIScrollView reached the top or bottom

IosObjective CIphoneUiscrollviewUiscrollviewdelegate

Ios Problem Overview


Is there a way to know if a UIScrollView has reached the top or bottom? Possibly in the method:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView 
                  willDecelerate:(BOOL)decelerate

Ios Solutions


Solution 1 - Ios

Implement the UIScrollViewDelegate in your class, and then add this:

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

Hope this is what you are after! Else have a tinker by adding more conditions to the above code and NSLog the value of scrollOffset.

Solution 2 - Ios

Well, contentInsets are also involved, when you try to determine whether scrollView is at the top or at the bottom. You might also be interested in cases when your scrollView is above the top and below the bottom. Here is the code I use to find top and bottom positions:

Swift:

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
    }

}

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

Solution 3 - Ios

If you want the code in 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
    }
}

Solution 4 - Ios

Simple and clean extension:

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

On GitHub:

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

Solution 5 - Ios

I figured out exactly how to do it:

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

Solution 6 - Ios

Do it like this(for 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
        }

        
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDuckView Question on Stackoverflow
Solution 1 - IosLukeView Answer on Stackoverflow
Solution 2 - IosAlexander DvornikovView Answer on Stackoverflow
Solution 3 - IosytbryanView Answer on Stackoverflow
Solution 4 - IosRudolf AdamkovičView Answer on Stackoverflow
Solution 5 - IosJPNView Answer on Stackoverflow
Solution 6 - IosRadu GhitescuView Answer on Stackoverflow