關於UIStatusBar隱藏的小探究

weixin_34321977發表於2016-08-25
935058-280d99388787e823.png
Paste_Image.png

最近聽說滴滴的折扣很給力,對於之前一直用微信叫車的我,就下了個客戶端,隨便玩了一下,注意到狀態列那小東西的變化,就去探究了一下,也就有了這篇文章...

本人小菜鳥一隻,文章也只是當作自己的筆記,並沒有複雜高深的內容,大神請忽略飄過~ 哈哈

UIStatusBar

對於StatusBar,由於其特殊性,蘋果對其並未像其他類一樣,暴露給我們單獨的h檔案,包含各個property以及相關API,就只是在UIApplication類提供相關幾個屬性跟API,所以我們平時對其的操作不外乎更改Style或者Hidden屬性;當然,還有橫豎屏轉換的問題,這裡我就不另作詳述了。

隱藏的方式

這裡要稍微講一下,在iOS 6的時候,我們通過修改專案plist檔案中的View controller-based status bar appearance 的布林值為No(預設為Yes),然後使用以下API來實現對statusBar的隱藏

- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation NS_DEPRECATED_IOS(3_2, 9_0, "Use -[UIViewController prefersStatusBarHidden]")

通常我們也是這麼幹的,通過配置一個Bool值引數傳入方法,來實現在需要的時候對statusBar做隱藏或顯示,同時也可配置是否伴隨動畫,類似這樣:

- (void)configeStatusBarHidden:(BOOL)hidden {
    if (hidden) {
        [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
    }else {
        [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
    }
}
935058-f0a06fa48f75539c.gif
article1.gif

這種修改plist檔案的方式在iOS7、8中也照樣可用,不過在iOS9中就報了警告,詳情可戳這裡,因此,我們應該把plist檔案中的那個value值改為Yes。並且從上面的API可以看到,iOS9之後,這個API也就DEPRECATED,官方也建議我們用-[UIViewController prefersStatusBarHidden]來代替,可能有童鞋會說,DEPRECATED也可以用呀,就像專案原先支援iOS7+ 使用UIAlertView,後來改為支援ios8+ ,無非就多個警告而已,也沒事呀. 但這裡會些許不同

plist檔案的value值改為Yes的時候,上面使用的- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation 將不起任何作用,反之,- (BOOL)prefersStatusBarHidden也會失效;
使用新的API來實現隱藏的功能需求

- (BOOL)prefersStatusBarHidden {
    UIApplication *app = [UIApplication sharedApplication];
    return !app.isStatusBarHidden;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationSlide;
}

但使用兩個API雖然可以實現隱藏功能,但我們即使設定了動畫,也沒看到任何動畫效果,也只是閃的一下就沒了


935058-39c98b241e57f24e.gif
article2.gif

那要怎樣才有動畫效果呢? 其實只要你夠細心,在看API文件的時候就會發現,在上面那兩個API的下面,有這麼個方法,

// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block.
- (void)setNeedsStatusBarAppearanceUpdate NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

相關的註釋說的非常清晰,我們可以把這個方法放在animation block裡面來達到動畫效果,事不宜遲,趕緊試試

[UIView animateWithDuration:0.33 animations:^{
        [self setNeedsStatusBarAppearanceUpdate];
    }];
935058-fc5603c26a7cfb8d.gif
article3.gif

</div>

這樣,滴滴的那個效果也就可以初步實現了,看下效果

- (IBAction)jump:(UIButton *)sender {
    sender.tag = !sender.tag;
    sender.tag ? [self showLeftView] : [self hideLeftView];
}
- (void)showLeftView {
    [UIView animateWithDuration:0.33 animations:^{
        self.leftView.transform = CGAffineTransformTranslate(self.leftView.transform, 200, 0);
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}
- (void)hideLeftView {
    [UIView animateWithDuration:0.33 animations:^{
        self.leftView.transform = CGAffineTransformTranslate(self.leftView.transform, -200, 0);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.33 animations:^{
            [self setNeedsStatusBarAppearanceUpdate];
        }];
    }];
}
935058-75b1afffb08684b2.gif
article4.gif

OK啦,可以收工了!!???

不不不,還沒完呢,還有話要說:

文章中所截圖的demo,最外層是有套了一個NavigationController的,然後通過在viewDidLoad設定隱藏navigationBar,因為仔細看發現滴滴應該也是隱藏了navigationBar的。其實這種需求還是比較少見的,而且也不適用於在Push介面的時候等;對了,如果你沒隱藏navigationBar,會出現這樣的情況:**

935058-861575a876ab841c.gif
article5.gif

最後,感謝您的閱讀,若文章有描述錯誤,望指正,非常感謝!

相關文章