In my app, I handle the change of the status bar frame by simply scaling the entire window to fit it in the remaining screen space:
- (void)application:(UIApplication *)application willChangeStatusBarFrame:
(CGRect)newStatusBarFrame {
UIView* window = [UIApplication sharedApplication].keyWindow;
[UIView animateWithDuration:1 / 3.f animations:^{
CGFloat heightDifference = newStatusBarFrame.size.height -
kWXDefaultStatusBarHeight;
[window setTransform:CGAffineTransformMakeScale(1.f,
heightScaleForCallStatusBar())];
[window setFrame:CGRectOffset(window.frame, 0, heightDifference -
kWXDefaultStatusBarHeight / 2)];
}];
}
This works, but if the window is scaled down during a call and I present a view controller with -presentViewController:animated:completion:
, the new controller doesn't use the scaled coordinate system, it uses an un-scaled one, and the UI gets broken. Any idea how to get the window's .transform
to transfer to new view controllers that are presented?
Alternatively, is there another way to handle the in-call status bar without re-arranging all of my UI elements?
Each view controller will have its view's frame set to the available space. The simplest way to handle this is to make sure that your view's springs-and-struts or autolayout properties allow for compression or expansion of the view. With the iPhone world now including multiple screen sizes, this is a good general practice.
However, if you are intent on using a transform on your view to handle resizing, you can implement
-viewWillLayoutSubviews
in your view controllers (probably in a common base class) to set a transform on the root view of the view controller.Edit:
On investigation, it appears that in-call status bar changes are not causing
-viewWillLayoutSubviews
to be called. However, the following code (in a common view controller base class) is working for me: