zoukankan      html  css  js  c++  java
  • iOS点击状态栏回到顶部底层实现原理

        在iOS开发中,苹果其实已经帮你实现了点击状态栏回到顶部这个功能,但我们在开发中会遇到点击不能回到顶部.其实这都和

    ScrollView中的一个属性scrollsToTop有关,我们先看看苹果关于这个属性的解释:

    // When the user taps the status bar, the scroll view beneath the touch which is closest to the status bar will be scrolled to top, but only if its `scrollsToTop` property is YES, its delegate does not return NO from `shouldScrollViewScrollToTop`, and it is not already at the top.
    // On iPhone, we execute this gesture only if there's one on-screen scroll view with `scrollsToTop` == YES. If more than one is found, none will be scrolled.
    @property(nonatomic) BOOL  scrollsToTop __TVOS_PROHIBITED;          // default is YES.

    其实根据苹果说的,如果当前窗口上,如果你不止一个scrollView的话,因为苹果不知道当你点击状态栏的时候,不知道让哪一个scrollView回到顶部,就会默认把这个属性赋值为NO;

       其实解决方法很简单,你确定好点击状态栏你需要哪个scrollView回到顶部,把他的属性赋值为YES,其他的scrollView 的这个属性赋值为NO.这样就可以利用系统的这个功能.

      scrollsToTop属性,苹果内部实现原理:

    思想: 苹果的底层就是使用递归,遍历当前窗口上所有的View,找到那个scrollView,并让它回到顶部,这也就解释了,为什么当前窗口上,如果有几个scrollView的话,scrollsToTop属性,会失效.

    假设我现在需要拿到窗口上的这个tableView,实现要它回到顶部

    1.获取主窗口,调用递归函数

    // 遍历窗口所有的子控件,看有没有tableView
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        
        // 获取窗口的所有子控件fetchTableView就是递归方法
        UITableView *tableView = [self fetchTableView:keyWindow];

    2.递归方法实现

     若是找到想要找到的tableView,就返回,否则就返回空

    - (UITableView *)fetchTableView:(UIView *)view
    {
        //以当前view为父控件,查找子控件
        for (UIView *childView in view.subviews) {
            
            if ([childView isKindOfClass:[UITableView class]]) {
                return (UITableView *)childView;
            }
            
             return  [self fetchTableView:childView];
    
        }
        
        return nil;
    }

    还有一种方法,在状态栏的一样的位置外面加一个window窗口

    static XMGStatusWindow *_statusWindow;
    
    + (void)show
    {
        XMGStatusWindow *statusWindow = [[XMGStatusWindow alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20)];
        //将这个window优先级设为最高
        statusWindow.windowLevel = UIWindowLevelAlert;
        statusWindow.backgroundColor = [UIColor clearColor];
        statusWindow.rootViewController = [[UIViewController alloc] init];
        statusWindow.hidden = NO;
        _statusWindow = statusWindow;
        
        // 当程序有多个窗口的时候,状态栏自动隐藏
        // 恢复状态栏显示
        [UIApplication sharedApplication].statusBarHidden = NO;
        
    }

    注: 在iOS10之后,苹果为了提高collectionView性能,苹果加了预加载,会同时在窗口上加载三个collectionView的cell,也就会导致你会在窗口上拿到三个cell.解决这个问题只需设置:

    collectionView.prefetchingEnabled = NO;

        

  • 相关阅读:
    Linux编译安装boost
    apue源码make:/usr/include/bits/timex.h:31:7: 错误:expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ be的解决方法
    POI导出word表格
    centos设置tomat开机自启
    算法题
    Oracle获取当前数据库的所有表名字段名和注释
    ajax提交文件
    Activemq Java
    Oracel 获取表数据大小
    Corn获取下一次执行时间
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/6018198.html
Copyright © 2011-2022 走看看