UIScrollView scroll to bottom programmatically

Viewed 238492

How can I make a UIScrollView scroll to the bottom within my code? Or in a more generic way, to any point of a subview?

30 Answers

You can use the UIScrollView's setContentOffset:animated: function to scroll to any part of the content view. Here's some code that would scroll to the bottom, assuming your scrollView is self.scrollView:

Objective-C:

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];

Swift:

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

Hope that helps!

It looks like all of the answers here didn't take the safe area into consideration. Since iOS 11, iPhone X had a safe area introduced. This may affect the scrollView's contentInset.

For iOS 11 and above, to properly scroll to the bottom with the content inset included. You should use adjustedContentInset instead of contentInset. Check this code:

  • Swift:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
  • Objective-C
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
  • Swift extension (this keeps the original contentOffset.x):
extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: contentOffset.x,
                                   y: contentSize.height - bounds.height + adjustedContentInset.bottom)
        setContentOffset(bottomOffset, animated: animated)
    }
}

References:

I also found another useful way of doing this in the case you are using a UITableview (which is a subclass of UIScrollView):

[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

If you somehow change scrollView contentSize (ex. add something to stackView which is inside scrollView) you must call scrollView.layoutIfNeeded() before scrolling, otherwise it does nothing.

Example:

scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
    scrollView.setContentOffset(bottomOffset, animated: true)
}

Swift:

You could use an extension like this:

extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
        setContentOffset(bottomOffset, animated: animated)
    }
}

Use:

scrollView.scrollsToBottom(animated: true)

For Horizontal ScrollView

If you like me has a Horizontal ScrollView and want to scroll to end of it (in my case to most right of it), you need to change some parts of the accepted answer:

Objective-C

CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];

Swift

let rightOffset: CGPoint = CGPoint(x: self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, y: 0)
self.scrollView.setContentOffset(rightOffset, animated: true)

Extend UIScrollView to add a scrollToBottom method:

extension UIScrollView {
    func scrollToBottom(animated:Bool) {
        let offset = self.contentSize.height - self.visibleSize.height
        if offset > self.contentOffset.y {
            self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
        }
    }
}

To scroll to the bottom end, we have to work with the target view maximum height.

import UIKit

extension UIScrollView {

    func scrollToBottomOf(targetView: UIView, animated: Bool) {
        setContentOffset(CGPoint(x:targetView.frame.minX, y:targetView.frame.maxY), animated: animated)
    }
}

//func invocation example 
optionScrollView.scrollToBottomOf(targetView: self.optionsStackView, animated: false)

Xamarin.iOS version for UICollectionView of the accepted answer for ease in copying and pasting

var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);          
CollectionView.SetContentOffset (bottomOffset, false);

Xamarin.iOS version of accepted answer

var bottomOffset = new CGPoint (0,
     scrollView.ContentSize.Height - scrollView.Frame.Size.Height
     + scrollView.ContentInset.Bottom);

scrollView.SetContentOffset (bottomOffset, false);
Related