答案似乎是容器視圖的自動調整掩碼根本不與狀態欄協調。別無選擇,只能編寫調整佈局的代碼。
由於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的佈局行爲。然後,所有這些代碼,對於每個視圖控制器,都必須重做...
嘗試設置[wantsFullScreenLayout](http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference /Reference.html#//apple_ref/occ/instp/UIViewController/wantsFullScreenLayout)爲true? –
我認爲這會導致視圖拉伸到整個窗口,無論statusBar是否可見,並且只會在半透明狀態欄中使用它。我錯了嗎?我更喜歡不透明的狀態欄和滑動佈局。 – Wienke