Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger scrollsToTop when UITableView is nested inside UIScrollView

Tags:

ios

iphone

I was wondering if anyone had had any luck triggering scrollsToTop (or by any other means) for a UITableView from the user tapping on the status bar when the UITableView is nested inside a UIScrollView that also observes this function? I know this probably isn't good practice, but in this instance the UX kind of calls for this type of hierarchy.

Either way, I've seen a whole bunch of proposals ranging from private methods (obviously not going to happen) to adding fake windows over the status bar (also not going to happen).

like image 740
Luke Avatar asked Sep 29 '11 04:09

Luke


3 Answers

Ok, so the answer here is two fold:

  1. You cannot have more than one UIScrollView (or classes deriving from or using UIScrollView - i.e. UITableView) on the same UIView with the property scrollsToTop set to YES. Pick the one you want to have the feature and make sure all others are no

    For example, do this:

    scrollView.scrollsToTop = NO;
    tableView.scrollsToTop = YES; // or not set
    
  2. Implement the UIScrollView delegate method scrollViewShouldScrollToTop: and return YES if the calling UIScrollView is the UITableView.

Props to this answer for mentioning the non-multiple scrollsToTop option.

like image 94
Luke Avatar answered Oct 10 '22 03:10

Luke


Just wanted to share a little function I wrote that helps debug these situations. As others have mentioned, you have to make sure only ONE scroll view has scrollsToTop turned on. If you embed complex view hierarchies it may be difficult to figure out which scroll view is the culprit. Just call this method after your view hierarchy is created, like in viewDidAppear. The level parameter is just to help indentation and you should seed it off with 0.

-(void)inspectViewAndSubViews:(UIView*) v level:(int)level {

NSMutableString* str = [NSMutableString string];

for (int i = 0; i < level; i++) {
    [str appendString:@"   "];
}

[str appendFormat:@"%@", [v class]];

if ([v isKindOfClass:[UITableView class]]) {
    [str appendString:@" : UITableView "];
}

if ([v isKindOfClass:[UIScrollView class]]) {
    [str appendString:@" : UIScrollView "];

    UIScrollView* scrollView = (UIScrollView*)v;
    if (scrollView.scrollsToTop) {
        [str appendString:@" >>>scrollsToTop<<<<"];
    }
}

NSLog(@"%@", str);

for (UIView* sv in [v subviews]) {
    [self inspectViewAndSubViews:sv level:level+1];
}}

Call it on your view controller's main view.

In the log, you should see >>>scrollsToTop<<< next to every view that has it turned on, making it easy to find the bug.

like image 21
Sherwin Zadeh Avatar answered Oct 10 '22 04:10

Sherwin Zadeh


One thing that helped me fix this problem is:

  • Verify every other UIScollView in the view hierarchy is set to scollsToTop = NO
  • Add sub view controllers as child view controllers using addChildViewController: It is not sufficient to only add the view as a subview to the parent's view.
like image 39
Kyle Redfearn Avatar answered Oct 10 '22 04:10

Kyle Redfearn