0

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

    2023.08.11 | admin | 134次围观

    一、前言

    在我们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
    

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论