iOS-點(diǎn)擊狀態(tài)欄自動(dòng)回到頂部功能實(shí)現(xiàn)詳解

狀態(tài)欄(statusBar)點(diǎn)擊自動(dòng)回到頂部效果需了,旨在為用戶在瀏覽界面時(shí)提供便利厌均,點(diǎn)擊狀態(tài)欄能夠快速回到界面頂部,所以主要針對(duì)可以滾動(dòng)的UIScrollView和其子類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)回到頂部的吮便。


    Snip20160717_10.png
  • 既然蘋(píng)果已經(jīng)提供了該功能,我們直接拿來(lái)用就好了幢踏,干嘛還要自己實(shí)現(xiàn)呢髓需?
  • 其實(shí)不然,在一些情況下該功能是無(wú)效的房蝉。比如僚匆,在窗口上同時(shí)存在兩個(gè)或兩個(gè)以上UIScrollView或其子類時(shí)。例如搭幻,將上面的tabView先添加到一個(gè)scrollView上咧擂,然后再將該scrollView添加到控制器的View上,此時(shí)點(diǎn)擊statusBar檀蹋,tabView不能自動(dòng)回到頂部松申。
  • 因?yàn)椋撔Ч欠裼行Вc 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(或其子類)水醋,如果scrollsToTop= YES 的ScrollView超過(guò)一個(gè)旗笔,所有ScrollView都不會(huì)響應(yīng)statusBar的點(diǎn)擊。
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.

小結(jié):

從上面分析我們可以得出結(jié)論:我們必須保證窗口上scrollsToTop == YES的ScrollView(及其子類)同一時(shí)間內(nèi)有且只有一個(gè)拄踪。這一樣才能保證點(diǎn)擊statusBar换团,該唯一存在的ScrollView能自動(dòng)回到頂部。


如何保證蘋(píng)果自帶的該功能一直好使呢宫蛆?

解決辦法:我們希望回到頂部的ScrollView的scrollsToTop =YES艘包,其他scrollsToTop = NO。

  • 有時(shí)耀盗,為了滿足某種需求想虎,我們?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)樗械膕crollView的scrollsToTop =YES忿薇。要想展示每個(gè)TableView時(shí)裙椭,點(diǎn)擊statusBar都有效,必須讓除了展示在最上面的TabView以外的所有的ScrollView的scrollsToTop =NO署浩。這就需要去判斷揉燃,到底顯示的是哪一個(gè)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沒(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)閟tatusBar其實(shí)是一個(gè)UIWindow啼染,且優(yōu)先級(jí)高于下面的keyWindow醋界。所以,添加的UIView會(huì)在statusBar的下面提完。
Snip20160717_14.png

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è)置透明即可打肝。


    Snip20160717_15.png

    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);
   }];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市粗梭,隨后出現(xiàn)的幾起案子争便,更是在濱河造成了極大的恐慌,老刑警劉巖断医,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滞乙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鉴嗤,警方通過(guò)查閱死者的電腦和手機(jī)斩启,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)醉锅,“玉大人兔簇,你說(shuō)我怎么就攤上這事∮菜#” “怎么了垄琐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)经柴。 經(jīng)常有香客問(wèn)我狸窘,道長(zhǎng),這世上最難降的妖魔是什么口锭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任朦前,我火速辦了婚禮,結(jié)果婚禮上鹃操,老公的妹妹穿的比我還像新娘。我一直安慰自己春哨,他們只是感情好荆隘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著赴背,像睡著了一般椰拒。 火紅的嫁衣襯著肌膚如雪晶渠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天燃观,我揣著相機(jī)與錄音褒脯,去河邊找鬼。 笑死缆毁,一個(gè)胖子當(dāng)著我的面吹牛番川,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脊框,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼颁督,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了浇雹?” 一聲冷哼從身側(cè)響起沉御,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昭灵,沒(méi)想到半個(gè)月后吠裆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烂完,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窜护。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片效斑。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柱徙,靈堂內(nèi)的尸體忽然破棺而出缓屠,到底是詐尸還是另有隱情,我是刑警寧澤护侮,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布敌完,位于F島的核電站,受9級(jí)特大地震影響羊初,放射性物質(zhì)發(fā)生泄漏滨溉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一长赞、第九天 我趴在偏房一處隱蔽的房頂上張望晦攒。 院中可真熱鬧,春花似錦得哆、人聲如沸脯颜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)栋操。三九已至闸餐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矾芙,已是汗流浹背舍沙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剔宪,地道東北人拂铡。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像歼跟,于是被迫代替她去往敵國(guó)和親和媳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容