2014-01-06 50 views
20

iOS開發人員肯定會知道狀態欄和着名的「幻燈片/漢堡/抽屜」問題。這個問題在這裏很好地解釋:http://uxmag.com/articles/adapting-ui-to-ios-7-the-side-menu如何淡出狀態欄,而不隱藏它

我使用MMDrawerController庫,它有一個很好的黑客,讓我們創建一個虛擬狀態欄就在容器視圖控制器上方。不幸的是,這並不是很好。有什麼新的消息?這個消息是我在一個應用程序(Tinder)完美地解決這個令人興奮的問題絆倒了。我創建了一個GIF,完美展示火種做什麼。

enter image description here

需要等待幾秒鐘對於看到GIF,因爲在它的錯誤,我不知道如何擺脫。只是等待一個/兩秒鐘,你就可以看到正確的GIF。


不管怎麼說,火種呢?當用戶點擊左上方的菜單按鈕並開始sw。時對吧狀態欄整齊地淡出。當視圖恢復到原始位置時,狀態欄將再次顯示。

我爲這個既高興又有點難過,因爲這意味着一個方式必須做,但我真的不知道如何實現它(也許黑客MMDrawerController)。任何幫助將非常感激。


重要

請注意一個事實,即該方法setStatusBarHidden:將完全隱藏狀態欄,這意味着整個看法是有高度-20px。這顯然不是解決方案,因爲你可以從gif中看到視圖不被拉伸。

+0

任何幫助讓我知道 – codercat

+0

您使用的是自動佈局嗎? – Alladinian

+1

難道不管應用程序設計爲隱藏或不隱藏狀態欄都顯示相同嗎?例如,通過對contentView的頂部使用約束而不是使用頂部佈局指南?這將解決-20px問題,但需要明顯調整應用程序。 – Taum

回答

20

你的主要問題是與MMDrawerController。如果你會發現它,你會發現很多方法狀態欄相關的,如setShowsStatusBarBackgroundViewsetStatusBarViewBackgroundColor等等。狀態欄隱藏時,代碼中的某些內容會將視圖向上推。

或者,您可以使用另一個抽屜控制器或使用自定義代碼。

這裏有一個簡單的方法如何accomplishe此:

enter image description here

ViewControllerA:

-(BOOL)prefersStatusBarHidden 
{ 
    return _hidden; 
} 
- (void)statusHide 
{ 
    [UIView animateWithDuration:0.4 animations:^() {[self setNeedsStatusBarAppearanceUpdate]; 
    }completion:^(BOOL finished){}]; 
} 

ViewControllerB:(集裝箱ViewControllerA)

- (IBAction)move:(UIButton *)sender 
{ 
    parent = (ViewController*)self.parentViewController; 
    parent.hidden = !parent.hidden; 
    CGRect frame = parent.blueContainer.frame; 
    if(parent.hidden) 
    { 
     frame.origin.x = 150; 
    } 
    else 
    { 
     frame.origin.x = 0; 
    } 

    [UIView animateWithDuration:1 animations:^() {parent.blueContainer.frame = frame;}completion:^(BOOL finished){}]; 
    [parent statusHide]; 
} 

對於iOS 6 compatieblty使用:

[[UIApplication sharedApplication] setStatusBarHidden:_hidden withAnimation:UIStatusBarAnimationFade]; 

表視圖和其他子視圖將保留在它們的位置,不會被推高。

編輯:

添加導航欄:

的UINavigationController將改變其UINavigationBar的對 或者44點或64點的高度,這取決於一個相當奇怪和 無證組的約束。如果UINavigationController檢測到 其視圖框架的頂部與UIWindow的頂部在視覺上相連,則它將繪製其導航欄,其高度爲64 點。如果其視圖的頂部與UIWindow的頂部 不相連(即使僅關閉一個點),則它將以「傳統」方式繪製其導航欄,其高度爲44點。這個邏輯是由UINavigationController執行的 ,即使它是在您的應用程序的視圖控制器層次結構內的多個子級 。有 是沒有辦法來防止這種行爲。

here

兩者你可以非常簡單地繼承UINavigationController並創建自己的導航欄,以避免這種annoyness。

+0

哦,很好看!你介意分享你的簡單測試項目嗎? :)無論如何,我沒有想到這個問題是「MMDrawerViewController」。我應該看看它的代碼,並試圖解決這個問題! –

+0

我剛剛試過做同樣的事情,你展示,它只適用於中央視圖控制器不是導航控制器。我認爲這是因爲導航控制器有一個導航欄連接到頂部佈局指南並嘗試修復它。你中心/右視圖控制器是一個導航控制器?淺藍色的視圖是一個導航欄? –

+0

是的,如果我試圖添加一個簡單的'UINavigationBar'它的工作原理,但如果控制器是一個具有自己的導航欄的導航控制器不起作用,因爲酒吧試圖保持連接到頂部。嗯 –

1

查看UIApplication上的方法setStatusBarHidden:withAnimation:。它將允許您顯示或隱藏狀態欄,並且動畫可以是無,淡入淡出或幻燈片。您只需添加一個電話即可隱藏欄杆,另一個則可在正確的時間顯示欄杆,並決定是否喜歡按照圖示進行淡入淡出,或者如果幻燈片更適合您。

https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/setStatusBarHidden:withAnimation

+0

感謝您的回答。請檢查更新。 –

+0

然後添加一個與導航欄相匹配的UIView,但與狀態欄具有相同的框架。您可能需要試驗一下時機以獲得您想要的效果。 – theMikeSwan

+0

如何?如果仔細查看Tinder,只需隱藏狀態欄而不會混淆新視圖。通過查看側菜單動畫運行時狀態欄的淡出狀態,可以看到這一點。 –

1

您可以使用-setStatusBarHidden:withAnimation:,如果你在-viewDidAppear:調整你的觀點框架,那麼你將不會看到任何拉伸。 請注意,自動佈局被禁用。

-(void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    CGRect frame = self.view.frame; 
    // adjust root view frame 
    frame.origin.y -= 20; 
    frame.size.height += 20; 

    [self.view setFrame:frame]; 

    // adjust subviews y position 
    for (UIView *subview in [self.view subviews]) 
    { 
     CGRect frame = subview.frame; 
     frame.origin.y += 20; 
     [subview setFrame:frame]; 
    } 
} 

- (IBAction)sliderChanged:(id)sender 
{ 
    UISlider *s = (UISlider *)sender; 
    if (s.value > .5) 
    { 
     UIApplication *app = [UIApplication sharedApplication]; 
     if (![app isStatusBarHidden]) 
      [app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; 
    } 
    else 
    { 
     UIApplication *app = [UIApplication sharedApplication]; 
     if ([app isStatusBarHidden]) 
      [app setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade]; 
    } 
} 

enter image description here

3

這裏是你應該怎麼做,在iOS的7:

@implementation ViewController 
{ 
    BOOL _hideStatusBar; 
} 

-(UIStatusBarStyle)preferredStatusBarStyle 
{ 
    return UIStatusBarStyleDefault; 
} 

-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation 
{ 
    return UIStatusBarAnimationFade; 
} 

-(BOOL)prefersStatusBarHidden 
{ 
    return _hideStatusBar; 
} 

-(void)setStatusBarHidden:(BOOL)hidden 
{ 
    [UIView animateWithDuration:1.0 animations:^{ 
     _hideStatusBar = hidden; 
     [self setNeedsStatusBarAppearanceUpdate]; 
    }]; 
} 

@end 
+1

這會工作,但只有這樣才能解決導航欄和子控制器滑動,如果你已經在導航欄中設置半透明= NO。 –

5

我不知道它是否會解決您的問題,但使用SWRevealViewController項目的效果幾乎相同。在的appDelegate我已經設置委託方法從這個類來做到這一點:

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { 
#ifdef DEBUG 
    NSArray *teste = @[@"FrontViewPositionLeftSideMostRemoved",@"FrontViewPositionLeftSideMost",@"FrontViewPositionLeftSide",@"FrontViewPositionLeft",@"FrontViewPositionRight",@"FrontViewPositionRightMost",@"FrontViewPositionRightMostRemoved"]; 
    NSLog(@"%@ %d", teste[position], position); 
#endif 
    if (position == FrontViewPositionRight) 
     [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; 
    UINavigationController *frontViewController = (id)revealController.frontViewController; 
    frontViewController.navigationBar.centerY += (position == FrontViewPositionRight) ? 20 : 0; // 20 == statusbar heihgt 
} 

- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { 
    if (position == FrontViewPositionLeft) 
     [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade]; 
} 

centerY是UIView的一個類別,它設置center.y無需處理設定的框架變量枯燥的一部分。

+0

這似乎工作得很好。好的趕上! – mattsven