Scroll to top of UITableView by tapping status bar

38,463

Solution 1

You get this for free, but you should check that the scrollsToTop attribute of your UITableView is YES.

When this does NOT work is when you have a UIScrollView (or descendant class like UITextView) object embedded inside another UIScrollView class (like UITableView). In this case, set scrollsToTop on the embedded UIScrollView class to NO. Then the tap-the-status-bar behavior will work.

Solution 2

If you came from Google and need a complete checklist:

  1. Check that you've set scrollsToTop=YES (per Mark's suggestion) on your UITableView
  2. Make sure that you've set scrollsToTop=NO on all OTHER UITableViews / UIScrollViews / UITextViews in your window, so that they're not intercepting the click. I've found myself printing out all the views in my window many times to debug this...
  3. Make sure that your table view is at 0/0 (x/y coordinates) within the window - this is how the system knows that it should pass the message

Solution 3

Using the information given in other answers, I added the following code to my UITableViewController get it to work:

- (void)viewDidLoad
{
    [super viewDidLoad];

    for (UITextView *view in self.view.subviews) {
        if ([view isKindOfClass:[UITextView class]]) {
            view.scrollsToTop = NO;
        }
    }

    self.tableView.scrollsToTop = YES;
}

This looks through all the views in the UITableViewController's hierarchy and turns off scrollsToTop on all the UITextViews that were intercepting the touch event. Then, ensured the tableView was still going to receive the touch.

You can mod this to iterate through other UITableViews / UIScrollViews / UITextViews that may be intercepting as well.

Hope this helps!

Solution 4

I had the same problem but fixed by following steps:

  1. Set scrollsToTop = YES for tableview you wanted to scroll to top.
  2. set scrollsToTop = NO for all other tableview or collection view or scrollview.
  3. If any of your tableview cell has collection view . Make sure you set scrollsToTop to NO for the collection view as well.

If your view controller/ navigation controller is added as a subview on another view controller, Make sure you set it as a child Controller.

Solution 5

I know this is quite an old one but hope this can help. Following what @MarkGranoff said, the scrollsToTop doesn't work if more than one UIScrollView, or its subclasses, has got it set to YES (default value), a sanity check is probably worth to check who's actually messing up with this behaviour. The simple method below loop over the subviews of your view and logs the scrollsToTop value of all the UIScrollView in your view. Preferably to be called in your viewDidAppear method.

- (void)checkForScrollViewInView:(UIView *)view {
    for (UIView *subview in [view subviews]) {
        if ([subview isKindOfClass:[UIScrollView class]]) {
            NSLog(@"scrollsToTop enabled: %i in scroll view %@", ((UIScrollView *)subview).scrollsToTop, subview);
        }
        if (subview.subviews.count > 0) {
            [self checkForScrollViewInView:subview];
        }
    }
}

This is just a debug code indeed. Once you find the scrollsToTop value for each one of the UIScrollView subclasses just make sure only one is set to YES.

Share:
38,463
iOSDev
Author by

iOSDev

Updated on March 10, 2020

Comments

  • iOSDev
    iOSDev over 4 years

    I know there's tons of code out there to scroll a tableview to the top, but I want to do this when the top status bar is tapped, just like in Apple's native apps. Is this possible?