2012-06-24 65 views
2

我讓用戶隨意顯示/隱藏狀態欄,並且我希望所有視圖都向下滑動/向上滑動。我認爲設置自動調整掩碼會照顧到這一點。我已經通過編程添加了導航控制器,所以我這樣做了:將狀態欄隱藏/顯示爲向上/向下滑動所有視圖

[self.view setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; 
[self.navigationController.view setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; 
[self.navigationController.navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin]; 

這沒有效果。

我在隱藏statusBar之前和之後打印了self.viewself.navigationController.view的框架矩形,它們保持完全相同的高度。

由於autoresizesSubviews默認爲YES,我懷疑這是問題所在。我不能正確設置自動識別屏蔽。有人知道我在做什麼錯嗎?

+1

嘗試設置[wantsFullScreenLayout](http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference /Reference.html#//apple_ref/occ/instp/UIViewController/wantsFullScreenLayout)爲true? –

+0

我認爲這會導致視圖拉伸到整個窗口,無論statusBar是否可見,並且只會在半透明狀態欄中使用它。我錯了嗎?我更喜歡不透明的狀態欄和滑動佈局。 – Wienke

回答

0

答案似乎是容器視圖的自動調整掩碼根本不與狀態欄協調。別無選擇,只能編寫調整佈局的代碼。

由於Apple沒有提供statusBar和其他元素之間的自動協調,你會認爲他們會讓我們自己做。但是,不,我們不允許直接設置statusBar框架。使狀態條重新定位動畫的唯一方法是通過UIStatusBarAnimationSlide,它使用自己的時間軸並且永遠不會匹配其他動畫。

但是,我們可以控制statusBar淡出的時間並將容器視圖與其一起滑動。子視圖的autoresize掩碼將完成剩下的工作。其實,這看起來相當不錯,和編碼,雖然有些怪異取景行爲複雜,是不是太痛苦:

UIApplication *appShared = [UIApplication sharedApplication]; 
CGFloat fStatusBarHeight = appShared.statusBarFrame.size.height; // best to get this once and store it as a property 
BOOL bHideStatusBarNow = !appShared.statusBarHidden; 
CGFloat fStatusBarHeight = appDelegate.fStatusBarHeight; 
if (bHideStatusBarNow) 
    fStatusBarHeight *= -1; 

CGRect rectView = self.view.frame; // must work with frame; changing the bounds won't have any effect 

// Determine the container view's new frame. 
// (The subviews will autoresize.) 
switch (self.interfaceOrientation) { 
    case UIInterfaceOrientationPortrait: 
    case UIInterfaceOrientationPortraitUpsideDown: 
     rectView.origin.y += fStatusBarHeight; 
     rectView.size.height -= fStatusBarHeight; 
     break; 
    case UIInterfaceOrientationLandscapeLeft: 
    case UIInterfaceOrientationLandscapeRight: 
     // In landscape, the view's frame will sometimes complement the orientation and sometimes not. 
     /* 
     Specifically, if view is loaded in landscape, its frame will reflect that; otherwise, the frame will always be in portrait orientation. 
     This is an issue only when the navBar is present. Regular view controllers can count on the frame staying in portrait orientation no matter what. 
     But regular view controllers have another oddity: In the upside-down orientations, you should adjust the height only; the origin takes care of itself. 
     */ 
     if (rectView.size.width < rectView.size.height) { 
      rectView.origin.x += fStatusBarHeight; 
      rectView.size.width -= fStatusBarHeight; 
     } 
     else { 
      rectView.origin.y += fStatusBarHeight; 
      rectView.size.height -= fStatusBarHeight; 
     } 
     break; 
    default: 
     break; 
} 

// The navBar must also be explicitly moved. 
CGRect rectNavBar = [self.navigationController.navigationBar frame]; 
rectNavBar.origin = CGPointMake(0.0f, rectNavBar.origin.y + fStatusBarHeight); 

// Perform the animated toggling and reframing. 
[UIView animateWithDuration:kAnimDurationToggleStatusBar animations:^{ 
    [appShared setStatusBarHidden:bHideStatusBarNow]; // you can add withAnimation:UIStatusBarAnimationSlide here and it will work, but the timing won't match 
    [self.navigationController.navigationBar setFrame:rectNavBar]; 
    [self.view setFrame:rectView]; 
}]; 

有沒有必要做任何事情到工具欄,這仍然緊盯着屏幕的底部 - - 只要您有而不是將窗口框架設置爲mainScreen.bounds。

一個障礙是如何獲得statusBar高度,當你想重新顯示它時,因爲statusBarFrame返回一個0區域矩形,如果它當前被隱藏。事實證明,無需動畫即可進行初步顯示/隱藏,只是爲了得到矩形,效果很好。沒有可見的閃光燈。

此外,如果您使用的是xib/nib,請確保其視圖的statusBar設置爲None。

也許有一天Apple會加強statusBar的佈局行爲。然後,所有這些代碼,對於每個視圖控制器,都必須重做...

相關問題