对任何数字进行硬编码总是与未来的证明背道而驰。你的担心是正确的。正确处理 statusBar 的隐藏有一些技巧。但是所有需要的信息都是可用的。
例如,UIApplication
单例有一个名为的属性statusBarFrame
,这正是它听起来的样子,aCGRect
的statusBar
框架。很酷的是,一旦你调用setStatusBarHidden:withAnimation:
了该属性,它就会给你新的帧,甚至在动画完成之前。所以实际上你只剩下一些基本的数学来调整view
's frame
。
简而言之,您的直觉是正确的;总是实时计算。
我用这样的类别方法取得了很好的成功。(即使在模拟器中切换通话状态栏(Command - T)):
@implementation UIApplication (nj_SmartStatusBar)
// Always designate your custom methods by prefix.
-(void)nj_setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation{
UIWindow *window = [self.windows objectAtIndex:0];
UIViewController *rootViewController = window.rootViewController;
UIView *view = rootViewController.view;
// slight optimization to avoid unnecassary calls.
BOOL isHiddenNow = self.statusBarHidden;
if (hidden == isHiddenNow) return;
// Hide/Unhide the status bar
[self setStatusBarHidden:hidden withAnimation:animation];
// Get statusBar's frame
CGRect statusBarFrame = self.statusBarFrame;
// Establish a baseline frame.
CGRect newViewFrame = window.bounds;
// Check if statusBar's frame is worth dodging.
if (!CGRectEqualToRect(statusBarFrame, CGRectZero)){
UIInterfaceOrientation currentOrientation = rootViewController.interfaceOrientation;
if (UIInterfaceOrientationIsPortrait(currentOrientation)){
// If portrait we need to shrink height
newViewFrame.size.height -= statusBarFrame.size.height;
if (currentOrientation == UIInterfaceOrientationPortrait){
// If not upside-down move down the origin.
newViewFrame.origin.y += statusBarFrame.size.height;
}
} else { // Is landscape / Slightly trickier.
// For portrait we shink width (for status bar on side of window)
newViewFrame.size.width -= statusBarFrame.size.width;
if (currentOrientation == UIInterfaceOrientationLandscapeLeft){
// If the status bar is on the left side of the window we move the origin over.
newViewFrame.origin.x += statusBarFrame.size.width;
}
}
}
// Animate... Play with duration later...
[UIView animateWithDuration:0.35 animations:^{
view.frame = newViewFrame;
}];
}
@end