2019独角兽企业重金招聘Python工程师标准>>>
一、前言
在我们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