- 應用場景需求:細心的人會發(fā)現(xiàn),在很多app應用中點擊頂部狀態(tài)欄會快速返回頂部,系統(tǒng)有幫忙實現(xiàn)這個功能,但是有條件;
- 1.如果是scrollView只有一個,或者是tableView只有一個
- 2.
scrollsToTop
屬性設置為YES,默認是就是YES或者是代理方法shouldScrollViewScrollToTop
返回值為YES
需求:在父子控制器中實現(xiàn)點擊頂部狀態(tài)欄返回頂部如圖:
test.gif
分析:
- 1.在頂部添加一個自定義的UIView,監(jiān)聽它的點擊;
- 2.查找所有的scrollView,修改它的偏移量;
1.添加一個窗口
// 聲明一個全局變量
static UIWindow *window_;
+ (void)show
{
// 延遲加載窗口,保證這個窗口在所有窗口的最上面
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
window_ = [[UIWindow alloc] init];
window_.frame = [UIApplication sharedApplication].statusBarFrame;
// 窗口默認顯示黑色
window_.backgroundColor = [UIColor clearColor];
// UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal
// 窗口默認等級是UIWindowLevelNormal,等級最低,放在最下層,點擊手勢被攔截,無法被監(jiān)聽到
window_.windowLevel = UIWindowLevelAlert;
// 默認是隱藏的
window_.hidden = NO;
[window_ addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(topWindowClick)]];
});
}
2.監(jiān)聽頂部的點擊手勢
+ (void)topWindowClick
{
// 主窗口
UIWindow *window = [UIApplication sharedApplication].keyWindow;
// 查找主窗口中的所有scrollView
[self findScrollViewsInView:window];
}
3.查找view中的所有scrollView
+ (void)findScrollViewsInView:(UIView *)view
{
// 窗口也繼承UIView
// 利用遞歸查找所有的子控件
for (UIView *subview in view.subviews) {
[self findScrollViewsInView:subview];
}
if (![view isKindOfClass:[UIScrollView class]]) return;
// 判斷是否跟window有重疊
if (![view intersectWithView:[UIApplication sharedApplication].keyWindow]) return;
// 如果是scrollView
UIScrollView *scrollView = (UIScrollView *)view;
// 修改offset
CGPoint offset = scrollView.contentOffset;
offset.y = - scrollView.contentInset.top;
[scrollView setContentOffset:offset animated:YES];
}