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

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 

一、前言

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

转载于:https://my.oschina.net/mexiaobai1315/blog/1502941

你可能感兴趣的:(iOS-点击状态栏返回到顶部效果)