美文网首页UITableVIewiOS技能收藏控件封装
ios-自定义点击状态栏滚回顶部

ios-自定义点击状态栏滚回顶部

作者: 没阳光的午后 | 来源:发表于2015-12-30 20:32 被阅读2179次

    点击状态栏滚回顶部这个功能是系统自带的,只需要设置self.scrollView.scrollsToTop = YES即可,但是这个属性有一个前提是窗口下必须只有一个可滚动的View才有效果,这时候就需要自定义创建一个窗口来完成这个功能

    添加窗口

    • AppDelegate创建一个新的窗口必须给这个窗口设置一个根控制器,否则会报错,这里可以通过dispatch_after来给添加窗口一个延时就可以不设置根控制器
    • 窗口是有级别的windowLevel,级别越高就越显示在顶部,如果级别一样,那么后添加的创建显示在顶部.级别分为三种,UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal,接下来创建一个创建并且添加一个监控
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            topWindow_ = [[UIWindow alloc] init];
            topWindow_.windowLevel = UIWindowLevelAlert;
            topWindow_.frame = [UIApplication sharedApplication].statusBarFrame;
            topWindow_.backgroundColor = [UIColor clearColor];
            topWindow_.hidden = NO;
            [topWindow_ addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(topWindowClick)]];
        });
    

    在监听方法中遍历子控件,如果是scrollView就滚回顶部

        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        for (UIView *subview in view.subviews) {
            [self searchAllScrollViewsInView:subview];
        }
        
        if (![view isKindOfClass:[UIScrollView class]]) return;
        
        // 找到了UIScrollView
        UIScrollView *scrollView = (UIScrollView *)view;
        [scrollView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
    

    但是这样会有一个BUG,如果屏幕旋转的话,添加的Viewframe会不正确,接下来解决这个BUG

    • 如果要旋转屏幕的话,必须给设置的窗口添加一个根控制器
    • 这个BUG的原因是Autoresizing,在旋转的时候,窗口的View宽高被拉伸造成frame不正确,这时候只需要设置View跟随窗口的变化而变化即可
    topWindow_.rootViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    

    上面代码还有个BUG是点击状态栏会将所有的ScrollView全部滚回顶部,这里需要判断当前View是否与窗口有重叠,重叠才滚回顶部

    
    - (BOOL)bs_intersectsWithAnotherView:(UIView *)anotherView
    {
        if (anotherView == nil) anotherView = [UIApplication sharedApplication].keyWindow;
        
        // 判断self和anotherView是否重叠
        CGRect selfRect = [self convertRect:self.bounds toView:nil];
        CGRect anotherRect = [anotherView convertRect:anotherView.bounds toView:nil];
        return CGRectIntersectsRect(selfRect, anotherRect);
    }
    

    以上方法可以判断不是同一坐标系的2个View是否重叠,并且如果anotherView为空的话,就返回窗口

    if (![scrollView bs_intersectsWithAnotherView:nil]) return
    

    在监听方法中加入以上代码即可完成功能

    相关文章

      网友评论

      • d994dc68be77:大神 按照你的方法做了 确实有用了,但是进入二级页面 状态栏的字体是变成黑色的 调用任何方法都改不过来 怎么办呢
      • 酱油葱:不错,本来想在微信朋友圈看类似的bug解决没有,结果发现它不让旋转:joy:

      本文标题:ios-自定义点击状态栏滚回顶部

      本文链接:https://www.haomeiwen.com/subject/vivihttx.html