Limit UITableView scroll speed like Instagram does it

8.5k views Asked by At

I'm trying to limit the scroll speed of my UITableView, exactly like Instagram does it.

If you check out Instagram, you'll notice that they have a limit on how fast you can scroll through the feed.

It's not set using "decelerationRate" since the limit doesn't affect the deceleration. It simply affects the how fast you can scroll through the feed. So if you try to do a "flick" gesture, you will hit Instagrams max scrolling speed and won't go as fast as in a normal UITableView.

Any guesses on how Instagram accomplishes this?

3

There are 3 answers

6
Nirav Gadhiya On

TableView has a property scrollView, This property will return internal scrollView of TableView. Use following...

tableview.scrollView.decelerationRate = UIScrollViewDecelerationRateFast;

ANOTHER WAY:

TableView will respond to scrollView delegate, so we need to implement scrollView's delegate like:

Take these global variables :

CGPoint lastOffset;
NSTimeInterval lastOffsetCapture;
BOOL isScrollingFast;

Implement scrollViewDidScroll like :

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {    
    CGPoint currentOffset = scrollView.contentOffset;
    NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];

    NSTimeInterval timeDiff = currentTime - lastOffsetCapture;
    if(timeDiff > 0.1) {
        CGFloat distance = currentOffset.y - lastOffset.y;
        //The multiply by 10, / 1000 isn't really necessary.......
        CGFloat scrollSpeedNotAbs = (distance * 10) / 1000; //in pixels per millisecond

        CGFloat scrollSpeed = fabsf(scrollSpeedNotAbs);
        if (scrollSpeed > 0.5) {
            isScrollingFast = YES;
            NSLog(@"Fast");
        } else {
            isScrollingFast = NO;
            NSLog(@"Slow");
        }        

        lastOffset = currentOffset;
        lastOffsetCapture = currentTime;
    }
}

Then implement scrollViewDidEndDragging like this :

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if( !decelerate )
    {
        NSUInteger currentIndex = (NSUInteger)(scrollView.contentOffset.x / scrollView.bounds.size.width);

        [scrollView setContentOffset:CGPointMake(scrollView.bounds.size.width * currentIndex, 0) animated:YES];
    }
}

Hope this may help you...

1
Rashad On

Use this:

self.tableview.scrollView.decelerationRate = UIScrollViewDecelerationRateFast;

As tableView is a subclass of UIScrollView, ScrollView delegate will work here. Hope this helps.. :)

Edit:

if tableView doesn't show scrollView property use:

self.tableView.decelerationRate
0
KrishnDip On

In Swift set like this

tableView.decelerationRate =  UIScrollView.DecelerationRate(rawValue: 0.5)

UIScrollView.DecelerationRate having two rate types normal and fast. By default its normal (approx value >= 0.9). didn't check about fast value.

To do like Instagram you need to check velocity using scrollViewWillEndDragging method.

check velocity, if its above some threshold then set decelerationRate as per your need.