当UITableView嵌套在UIScrollView中时如何触发scrollsToTop?

5
我想知道是否有人成功地通过点击状态栏来触发UITableView的scrollsToTop(或通过其他方式),即使UITableView嵌套在也会响应此函数的UIScrollView中?我知道这可能不是一个好的做法,但在这种情况下,UX似乎需要这种层次结构。
无论如何,我看到过很多提案,从私有方法(显然不可能)到在状态栏上添加虚拟窗口(也不可能)。

你的TableView位于哪个控件中? - stack2012
UIScrollView。抱歉,问题已更新。 - Luke
你尝试过在滚动视图和表格中同时使用scrollsToTop吗? - stack2012
是的,对我没用。 - Luke
4个回答

13

好的,这里的答案有两个方面:

  1. 在同一个UIView上,你不能同时拥有超过一个UIScrollView(或从UIScrollView派生或使用UIScrollView的类--即UITableView),并且设置scrollsToTop属性为YES。选择你想要具备该功能的那一个,并确保其他所有的都没有该属性。

    例如,这样做:

scrollView.scrollsToTop = NO;
tableView.scrollsToTop = YES; // or not set
  • 实现UIScrollView的代理方法scrollViewShouldScrollToTop:,并在调用的UIScrollView为UITableView时返回YES

  • 感谢这个答案提到了非多重scrollsToTop选项。


    12

    想要分享一个我写的小函数,可以帮助调试这些情况。正如其他人所提到的,你必须确保只有一个滚动视图开启了scrollsToTop选项。如果嵌入了复杂的视图层次结构,可能很难确定哪个滚动视图是罪魁祸首。在视图层次结构创建后(例如在viewDidAppear中),只需调用此方法即可。level参数只是为了帮助缩进,你应该从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];
    }}
    

    在您的视图控制器的主视图上调用它。

    在日志中,您应该看到每个启用了此功能的视图旁边都有 >>>scrollsToTop<<< 的标记,这样可以轻松找到错误。


    1
    这解决了我的问题!谢谢!我希望我能为这个小宝石给你更多的支持。 - dacoinminster
    1
    你刚刚为我节省了几个小时!谢谢。 - Gasper
    1
    哎呀!超级有用的方法。典型的,“为什么我没想到这个”时刻。 - dezinezync
    你需要从 view.window 往下看! - David H

    1

    帮助我解决这个问题的一件事是:

    • 验证视图层次结构中的每个其他UIScollView是否设置为scollsToTop = NO
    • 使用addChildViewController:将子视图控制器添加为子视图控制器。仅将视图添加为父视图的子视图是不够的。

    -2
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    
    [gridTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
    

    希望能够帮到你 :)

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接