美文网首页ios键盘上的鼓手iOS开发指南
iOS-点击状态栏返回到顶部效果

iOS-点击状态栏返回到顶部效果

作者: Super_Yi | 来源:发表于2015-12-31 22:41 被阅读10066次
    一、前言

    在我们IOS开发中,UIScrollView自带有点击顶部状态栏自动返回顶部的效果,不过这个效果是有约束条件的:

    
    // 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(包含UITableView/UICollectionView),如汽车之家、网易新闻、爱奇艺等等应用,这时候,系统默认的点击状态栏返回到顶部效果就会失效,我们就得自己自定义控件来实现此功能了。

    二、主要技术点

    抛开常用的技术点,主要用到的技术点有:

    • 多窗口应用
    • 递归
    • 坐标系转换
    • 触摸事件响应(横竖屏切换时需要)
    PS:由于最近刚回武汉忙着找工作,所以没有花太多时间在简书上面,我先把代码放上来,后续再重新整理
    
    #import "TopWindow.h"
    
    @implementation TopWindow
    
    static UIWindow *topWindow_;
    
    /**
     * 显示顶部窗口
     */
    + (void)show
    {
        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)]];
        });
    }
    
    /**
     * 监听顶部窗口点击
     */
    + (void)topWindowClick
    {
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        [self searchAllScrollViewsInView:keyWindow];
    }
    
    /**
     * 找到参数view中所有的UIScrollView
     */
    + (void)searchAllScrollViewsInView:(UIView *)view
    {
        // 递归遍历所有的子控件
        for (UIView *subview in view.subviews) {
            [self searchAllScrollViewsInView:subview];
        }
        
        
        // 判断子控件类型(如果不是UIScrollView,直接返回)
        if (![view isKindOfClass:[UIScrollView class]]) return;
        
        // 找到了UIScrollView
        UIScrollView *scrollView = (UIScrollView *)view;
        
        // 判断UIScrollView是否和window重叠(如果UIScrollView跟window没有重叠,直接返回)
        if (![scrollView bs_intersectsWithAnotherView:nil]) return;
        
        // 让UIScrollView滚动到最前面
        // 让CGRectMake(0, 0, 1, 1)这个矩形框完全显示在scrollView的frame框中
        [scrollView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
    }
    
    @end
    

    相关文章

      网友评论

      • xiao小马哥:其实不用这么麻烦,你只要设置其中想要回到顶部的scrollview的scrollToTop属性为YES,其他的都为NO,就可以了
      • CoderJackieYip:这种方法,可行是可行,MJ的方案,不过有个巨坑啊。比如分享功能:从当前app跳转到分享微博app,然后跳转回来自己的app之后,状态栏上左上角会显示“返回微博”。此时点击“返回微博”,就没办法响应 了,因为点击事件被这个topWindow接收了。
      • 90823cc8f71b:当action sheet弹出时,UIWindowDidResignKeyNotification通知被发送了。此时检查app所在的window,发现它已经不再是key window了。那么通过[UIApplication sharedApplication].keyWindow,获取window进行操作时,就会出错,请问怎么解决?
      • JaromeHuang:状态栏被改为黑色的了
      • 885389eb08b2:上面的人都确定能用???iOS9之后不是都得给window加一个根控制器???要不直接崩溃!!
        Dayu大鱼:@沙子LOVE 我吧window 的背景色 clearColor 了 , 我的能运行, 你试试
        沙子LOVE:@Hissia Xcode 7 现在也都得给window加一个根控制器 ,不管什么iOS系统。。 我加了根控制器,能实现功能,但顶部发生变化了,一坨黑,你有出现吗? 你是怎么解决的???
      • 茄子_Apple:现在是在武汉工作吗?
        coderboy001:@i_茄子 成都
      • d9431116937e:不知道出现这个问题没有,点击二级页面的状态栏,如果不进行上拉刷新操作,能正常回滚到原来的位置,但是如果上拉刷新了,回滚上去下拉刷新控件会出现在原来-offset.y的位置
      • d994dc68be77:大神 按照你的方法做了 确实有用了,但是进入二级页面 状态栏的字体是变成黑色的 调用任何方法都改不过来 怎么办呢
        Super_Yi:@如意葫芦 没明白你的表述
        d9431116937e:@如意葫芦 两种解决方案:1.在info.plist中增加一个字段,就是那个View controller-based status bar appearance,二级页面设置白色,返回时再设置过来
        2.二级页面设置窗口隐藏,返回时显示
      • 系统盘:很显然,我的失效了,我也用的这个方法,但是到一个scrollerview承载多个tableview时候,不知道发什么疯没用
      • YimG: [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, 0) animated:YES];
        :stuck_out_tongue_winking_eye:
      • YimG:如果一个ScrollView 里面有多个并排的tablview 那怎么办?
        Super_Yi:@YimG 递归遍历所有的ScrollView,找到和窗口重叠的,会返回的顶部,其他的不会返回
      • iHTCboy:判断UIScrollView是否和window重叠(如果UIScrollView跟window没有重叠,直接返回)
        这个方法的代码是什么?
        6e7261f07368:@iHTCboy 然后最后一句换成这个 [scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
        最后居然行了, :joy:
        6e7261f07368:@iHTCboy 我硬是写成这个了,不知道对不对 if (!( (topWindow_.frame.origin.x+topWindow_.frame.size.width >=scrollView.frame.origin.x) && (topWindow_.frame.origin.x+topWindow_.frame.size.width <= scrollView.frame.origin.x+scrollView.frame.size.width)))
        return;

      本文标题:iOS-点击状态栏返回到顶部效果

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