6

How would I go about allowing a UITableView to bounce when it reaches the bottom, but not the top. Essentially I'm adding a UIImageView as my TableView's section header, but currently if I pull up at the top there's an ugly space between my UIImageView and my UINavigationBar.

I look at this question but I don't really understand the solution. Would somebody mind elaborating?

Community
  • 1
  • 1
Apollo
  • 8,874
  • 32
  • 104
  • 192

2 Answers2

11

The question you link to has 2 different solutions. As the delegate of the table view you are already the scroll view delegate, so you could implement something like (this is the answer that isn't tagged as correct in the other question...):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    scrollView.bounces = (scrollView.contentOffset.y > 10);
}
Wain
  • 118,658
  • 15
  • 128
  • 151
  • huh, I get the following error: Invalid operands to binary expression ('CGPoint' (aka 'struct CGPoint') and 'int'). Do you know what this means? – Apollo Aug 01 '13 at 21:14
  • Yep, it means I missed 2 characters. You can't compare a `CGPoint` to an `int`... – Wain Aug 01 '13 at 21:20
  • ah I see =) This solution works almost perfectly. If I accelerate very quickly upward, it flickers a little bit against the background. Is there a way to prevent that from happening? – Apollo Aug 01 '13 at 21:23
  • 10 was an arbitrary value, you can make that bigger depending on how big the content of the scroll view is. You could also put the check in a different delegate method (like `scrollViewDidEndDragging:willDecelerate:`). – Wain Aug 01 '13 at 21:28
  • Got it. I'll play around with it. Thanks again. – Apollo Aug 01 '13 at 21:30
  • 1
    Apologies for downvoting but this solution http://stackoverflow.com/questions/17166983/uitableview-bounce-bottom-edge-only is better because in this implemenation the view still scrolls slightly at the top before changing the bounce property. Basically, there's no need to manipulate the bounce property – Royston Yinkore Jun 25 '15 at 12:24
  • If you make check against larger number than 10 you will most probably not get flickering at the top. Upvote because this solution suits me more than @RoystonYinkore 's linked one since it doesn't introduce another point of `contentOffset` change for which I would have to account. – iur Jan 29 '18 at 10:49
  • Oh well, apparently when you block bouncing it blocks content offset so I have to deal with it still :( – iur Jan 29 '18 at 14:08
4

The contentOffset is the distance between the origin of your frame (0, 0) and the origin of the first cell.

iOS: The default coordinate system has its origin at the upper left of the drawing area, and positive values extend down and to the right from it. You cannot change the default orientation of a view’s coordinate system in iOS—that is, you cannot “flip” it.

Initially, the contentOffset is zero. If you've scrolled past the top of the list (dragging finger downwards), then the contentOffset will be negative. If you've scrolled down the list (first cell is above the frame), then the contentOffset will be positive.

#pragma mark - UIScrollViewDelegate 
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat maxOffset = (scrollView.contentSize.height - scrollView.frame.size.height);
    CGFloat originOffset = 0;
    // Don't scroll below the last cell.
    if (scrollView.contentOffset.y >= maxOffset) {
        scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, maxOffset);

    // Don't scroll above the first cell.
    } else if (scrollView.contentOffset.y <= originOffset) {
        scrollView.contentOffset = CGPointZero;
    }
}
iamreptar
  • 1,461
  • 16
  • 29