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;

        

  • 相关阅读:
    System.Web.Security下提供了非常简单的MD5加密算法,但处在非Web层的项目要怎么使用MD5加密呢?
    切换用户账户访问共享 记
    从盛大通行证上摘下来的身份证验证代码
    HA_Xenu1.3.6 使用手记
    asp.net跨域共享session(不能跨主机名)
    应用程序池自动关闭
    忘记 win2003 密码 记
    Ajax 入门 【学习手记】
    转载 防盗链
    超链接的 target
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/6018198.html
Copyright © 2011-2022 走看看