前言
大家都知道實現狀態列(statusBar)點擊自動回到頂部效果,旨在為使用者在瀏覽介面時提供便利,點擊狀態列能夠快速回到介面頂部,所以主要針對可以滾動的UIScrollView
和其子類UITableVIew
和UICollectionView
。
這裡將從以下幾個方面實現該功能。
1.蘋果內建功能
分析:
首先,蘋果自己已經提供了該功能,往上滑動tabView
,點擊statusBar
,tableView
會自動回到初始位置。如下圖所示,此時點擊statusBar
,螢幕最上方顯示的將是第一個cell
。在一個控制器上添加一個tabView
,那麼預設點擊statusBar
是可以自動回到頂部的。
既然蘋果已經提供了該功能,我們直接拿來用就好了,幹嘛還要自己實現呢?
其實不然,在一些情況下該功能是無效的。比如,在視窗上同時存在兩個或兩個以上UIScrollView
或其子類時。例如,將上面的tabView
先添加到一個scrollView
上,然後再將該scrollView
添加到控制器的View
上,此時點擊statusBar
,tabView不能自動回到頂部。
因為,該效果是否有效,與 scrollsToTop
屬性相關。查看官方文檔,以下幾點值得注意:
1.預設情況下scrollsToTop
是為YES的,只有當該屬性為YES時,點擊statusBar
才有效。
2.該效果是讓距離statusBar
最近的ScrollView
自動回到頂部
3.在iPhone螢幕上方,當存在多個ScrollView
(或其子類),如果scrollsToTop= YES
的ScrollView
超過一個,所有ScrollView
都不會響應statusBar
的點擊。
小結:
從上面分析我們可以得出結論:我們必須保證視窗上scrollsToTop == YES
的ScrollView
(及其子類)同一時間內有且只有一個。這一樣才能保證點擊statusBar,該唯一存在的ScrollView
能自動回到頂部。
如何保證蘋果內建的該功能一直好使呢?
解決辦法:我們希望回到頂部的ScrollView
的scrollsToTop =YES
,其他scrollsToTop = NO
。
有時,為了滿足某種需求,我們在一個scrollView
上面會添加多個TabView
,實現上下滑動顯示cell
的不同內容,左右滑動可以切換不同的tabView
,這時點擊statusBar
是沒有效果的。因為所有的scrollView
的scrollsToTop =YES
。要想展示每個TableView
時,點擊statusBar
都有效,必須讓除了展示在最上面的TabView
以外的所有的ScrollView
的scrollsToTop =NO
。這就需要去判斷,到底顯示的是哪一個TabView
。
參考代碼如下:
1.讓最下面的scrollView
,scrollsToTop =NO
。其他TableView
都是該scrollView
的子類。
2.遍曆判斷
// 控制scrollView的scrollsToTop屬性 for (NSInteger i = 0; i < self.childViewControllers.count; i++) { UIViewController *childVc = self.childViewControllers[i]; // 如果控制器的view沒有被建立,跳過 if (!childVc.isViewLoaded) continue; // 如果控制器的view不是scrollView,就跳過 if (![childVc.view isKindOfClass:[UIScrollView class]]) continue; // 如果控制器的view是scrollView UIScrollView *scrollView = (UIScrollView *)childVc.view; scrollView.scrollsToTop = (i == index); }
2.自己實現
在statusBar
的地區添加一個遮蓋,監聽遮蓋的點擊事件。
UIView
首先我們想到用UIView
來做這個遮蓋。但是,在這裡我們使用UIView
是著不住statusBar
的,UIView
會一直在statusBar
的下面,所以不能接收點擊事件。因為statusBar
其實是一個UIWindow
,且優先順序高於下面的keyWindow
。所以,添加的UIView
會在statusBar
的下面。
UIWindow
由於優先順序的關係,我們可以用一個UIWindow
來做遮蓋,設定遮蓋window
的優先順序高於statusBar
即可。當然,設定最高優先順序(UIWindowLevelAlert
)肯定是可以的。然後給遮蓋Window
添加一個點擊事件,背景色設定透明即可。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIWindow * coverWindow =[[UIWindow alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20)]; self.coverWindow = coverWindow; coverWindow.hidden = NO; coverWindow.backgroundColor = [UIColor redColor]; coverWindow.windowLevel = UIWindowLevelAlert; //添加手勢 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(coverWindowClick)]; [self.coverWindow addGestureRecognizer:tap]; });
- (void)coverWindowClick { [UIView animateWithDuration:0.5 animations:^{ self.tableView.contentOffset = CGPointMake(0, 0); }];}
AppDelegate中直接監聽statusBar的點擊
在AppDelegate
中實現touchesBegan:
方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { if ([touches.anyObject locationInView:nil].y > 20) return; [[NSNotificationCenter defaultCenter]postNotificationName:@"click" object:nil];}
接收通知,修改tabView
的contentOffset
- (void)coverWindowClick { [UIView animateWithDuration:0.5 animations:^{ self.tableView.contentOffset = CGPointMake(0, 0); }];}
總結
以上就是這篇文章的全部內容,希望對大家開發IOS能有所協助,如果有疑問大家可以留言交流,謝謝大家對雲棲社區的支援。