iOS實(shí)現(xiàn)點(diǎn)擊狀態(tài)欄自動(dòng)回到頂部效果詳解
前言
大家都知道實(shí)現(xiàn)狀態(tài)欄(statusBar)點(diǎn)擊自動(dòng)回到頂部效果,旨在為用戶(hù)在瀏覽界面時(shí)提供便利,點(diǎn)擊狀態(tài)欄能夠快速回到界面頂部,所以主要針對(duì)可以滾動(dòng)的UIScrollView
和其子類(lèi)UITableVIew
和UICollectionView
。
這里將從以下幾個(gè)方面實(shí)現(xiàn)該功能。
1.蘋(píng)果自帶功能
分析:
首先,蘋(píng)果自己已經(jīng)提供了該功能,往上滑動(dòng)tabView
,點(diǎn)擊statusBar
,tableView
會(huì)自動(dòng)回到初始位置。如下圖所示,此時(shí)點(diǎn)擊statusBar
,屏幕最上方顯示的將是第一個(gè)cell
。在一個(gè)控制器上添加一個(gè)tabView
,那么默認(rèn)點(diǎn)擊statusBar
是可以自動(dòng)回到頂部的。
既然蘋(píng)果已經(jīng)提供了該功能,我們直接拿來(lái)用就好了,干嘛還要自己實(shí)現(xiàn)呢?
其實(shí)不然,在一些情況下該功能是無(wú)效的。比如,在窗口上同時(shí)存在兩個(gè)或兩個(gè)以上UIScrollView
或其子類(lèi)時(shí)。例如,將上面的tabView
先添加到一個(gè)scrollView
上,然后再將該scrollView
添加到控制器的View
上,此時(shí)點(diǎn)擊statusBar
,tabView不能自動(dòng)回到頂部。
因?yàn)?,該效果是否有效,與 scrollsToTop
屬性相關(guān)。查看官方文檔,以下幾點(diǎn)值得注意:
1.默認(rèn)情況下scrollsToTop
是為YES的,只有當(dāng)該屬性為YES時(shí),點(diǎn)擊statusBar
才有效。
2.該效果是讓距離statusBar
最近的ScrollView
自動(dòng)回到頂部
3.在iPhone屏幕上方,當(dāng)存在多個(gè)ScrollView
(或其子類(lèi)),如果scrollsToTop= YES
的ScrollView
超過(guò)一個(gè),所有ScrollView
都不會(huì)響應(yīng)statusBar
的點(diǎn)擊。
小結(jié):
從上面分析我們可以得出結(jié)論:我們必須保證窗口上scrollsToTop == YES
的ScrollView
(及其子類(lèi))同一時(shí)間內(nèi)有且只有一個(gè)。這一樣才能保證點(diǎn)擊statusBar,該唯一存在的ScrollView
能自動(dòng)回到頂部。
如何保證蘋(píng)果自帶的該功能一直好使呢?
解決辦法:我們希望回到頂部的ScrollView
的scrollsToTop =YES
,其他scrollsToTop = NO
。
有時(shí),為了滿(mǎn)足某種需求,我們?cè)谝粋€(gè)scrollView
上面會(huì)添加多個(gè)TabView
,實(shí)現(xiàn)上下滑動(dòng)顯示cell
的不同內(nèi)容,左右滑動(dòng)可以切換不同的tabView
,這時(shí)點(diǎn)擊statusBar
是沒(méi)有效果的。因?yàn)樗械?code>scrollView的scrollsToTop =YES
。要想展示每個(gè)TableView
時(shí),點(diǎn)擊statusBar
都有效,必須讓除了展示在最上面的TabView
以外的所有的ScrollView
的scrollsToTop =NO
。這就需要去判斷,到底顯示的是哪一個(gè)TabView
。
參考代碼如下:
1.讓最下面的scrollView
,scrollsToTop =NO
。其他TableView
都是該scrollView
的子類(lèi)。
2.遍歷判斷
// 控制scrollView的scrollsToTop屬性 for (NSInteger i = 0; i < self.childViewControllers.count; i++) { UIViewController *childVc = self.childViewControllers[i]; // 如果控制器的view沒(méi)有被創(chuàng)建,跳過(guò) if (!childVc.isViewLoaded) continue; // 如果控制器的view不是scrollView,就跳過(guò) if (![childVc.view isKindOfClass:[UIScrollView class]]) continue; // 如果控制器的view是scrollView UIScrollView *scrollView = (UIScrollView *)childVc.view; scrollView.scrollsToTop = (i == index); }
2.自己實(shí)現(xiàn)
在statusBar
的區(qū)域添加一個(gè)遮蓋,監(jiān)聽(tīng)遮蓋的點(diǎn)擊事件。
UIView
首先我們想到用UIView
來(lái)做這個(gè)遮蓋。但是,在這里我們使用UIView
是著不住statusBar
的,UIView
會(huì)一直在statusBar
的下面,所以不能接收點(diǎn)擊事件。因?yàn)?code>statusBar其實(shí)是一個(gè)UIWindow
,且優(yōu)先級(jí)高于下面的keyWindow
。所以,添加的UIView
會(huì)在statusBar
的下面。
UIWindow
由于優(yōu)先級(jí)的關(guān)系,我們可以用一個(gè)UIWindow
來(lái)做遮蓋,設(shè)置遮蓋window
的優(yōu)先級(jí)高于statusBar
即可。當(dāng)然,設(shè)置最高優(yōu)先級(jí)(UIWindowLevelAlert
)肯定是可以的。然后給遮蓋Window
添加一個(gè)點(diǎn)擊事件,背景色設(shè)置透明即可。
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; //添加手勢(shì) 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中直接監(jiān)聽(tīng)statusBar的點(diǎn)擊
在AppDelegate
中實(shí)現(xiàn)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); }]; }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容,希望對(duì)大家開(kāi)發(fā)IOS能有所幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- iOS 自定義狀態(tài)欄和導(dǎo)航欄詳細(xì)介紹
- 詳解在iOS App中自定義和隱藏狀態(tài)欄的方法
- iOS 隱藏導(dǎo)航條和狀態(tài)欄實(shí)現(xiàn)方法
- 圖文講解如何解決App的iOS 7頂部狀態(tài)欄適配問(wèn)題
- iOS 設(shè)置狀態(tài)欄的背景顏色方法
- 深入理解iOS的狀態(tài)欄
- iOS在狀態(tài)欄上顯示提醒信息的功能定制
- IOS點(diǎn)擊按鈕隱藏狀態(tài)欄詳解及實(shí)例代碼
- IOS 開(kāi)發(fā)狀態(tài)欄隱藏的實(shí)現(xiàn)辦法
- iOS狀態(tài)欄、導(dǎo)航欄的一些筆記分享
相關(guān)文章
Reactnative-iOS回調(diào)Javascript的方法
這篇文章主要介紹了Reactnative-iOS回調(diào)Javascript的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09IOS 單擊手勢(shì)的添加實(shí)現(xiàn)代碼
這篇文章主要介紹了IOS 單擊手勢(shì)的添加實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05iOS開(kāi)發(fā)之(APNS)遠(yuǎn)程推送實(shí)現(xiàn)代碼 附證書(shū)與真機(jī)調(diào)試
這篇文章主要為大家詳細(xì)介紹了iOS開(kāi)發(fā)之(APNS)遠(yuǎn)程推送實(shí)現(xiàn)代碼,附證書(shū)與真機(jī)調(diào)試,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09