iPhone - Typical problem with full screen and status bar
In my application by default status bar is visible. And my app supports landscape as well as portrait orientations. When I want to play the video, i'm hiding the status bar, so that my video will be shown full screen. And when video completes, i'm bringing the status bar back.
I'm using following code to show the video:
UIWindow* window = [[UIApplication sharedApplication] keyWindow];
[window addSubview:playerView];
(I can't use view controllers in my code. That's a restriction)
Now the problem: My app is in landscape now, on click of a button, i'll hide the status bar and starts playing video. When video is playing, i change the orientation of the phone to portrait and I allowed video to complete. When video completed, the device is still in portrait mode, player view is removed and 开发者_Python百科status bar is shown again. Now I noticed that my portrait view is moved 20 pixels up and over that the status bar is showing. But when I started the app for firs time, status bar is shown first and below it, my view is shown.
How should I handle this situation?
In simple use the following code in a view controller.
- (void)viewDidLoad {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self performSelector:@selector(showStatusAgain) withObject:nil afterDelay:6.0];
[super viewDidLoad];
}
-(void)showStatusAgain
{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
when u run the app with above code, it will start in portrait. now rotate it to landscape. and you can notice the issue.
I encountered a similar problem, which I solved with a category on UINavigationController.
UINavigationController+LayoutCorrecting.h:
@interface UINavigationController (LayoutCorrecting)
- (void)recalculateNavigationBarFrameRelativeToStatusBar;
@end
UINavigationController+LayoutCorrecting.m:
#import "UINavigationBar+LayoutCorrecting.h"
#import "UIViewAdditions.h"
@implementation UINavigationController (LayoutCorrecting)
- (void)recalculateNavigationBarFrameRelativeToStatusBar {
CGRect sbf = [[UIApplication sharedApplication] statusBarFrame];
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
self.navigationBar.top = sbf.size.width;
else
self.navigationBar.top = sbf.size.height;
}
@end
If you tweak this category a bit by declaring it on UIViewController, and making sure it adjusts controller.view.frame rather than navigationBar.top, I think you'll be good to go. Just make sure to call the category method on your view controller after your movie finishes playing and you've already shown the status bar.
And just for the sake of staving off any confusion, it's probably worth mentioning you need to use the width of the status bar in landscape mode because UIWindow's coordinate system always works as though it's in portrait, despite how you hold the device. This is in contrast to subviews (UIView instances) that get managed by a UIViewController, which benefit from automatic coordinate transformations.
P.S.: Since you're going to have to tweak your view's frame in a window context, this function may also help.
CGRect CGRectOffsetRectForOrientation(CGRect rect, CGFloat dx, CGFloat dy, UIInterfaceOrientation orientation) {
CGRect newRect = rect;
switch (orientation) {
case UIInterfaceOrientationPortrait:
newRect.origin.x += dx;
newRect.origin.y += dy;
break;
case UIInterfaceOrientationPortraitUpsideDown:
newRect.origin.x -= dx;
newRect.origin.y -= dy;
break;
case UIInterfaceOrientationLandscapeLeft:
newRect.origin.y -= dx;
newRect.origin.x += dy;
break;
case UIInterfaceOrientationLandscapeRight:
newRect.origin.y += dx;
newRect.origin.x -= dy;
break;
default:
break;
}
return newRect;
}
Try to update the status bar style when you show it:
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefualt];
精彩评论