I have a UIWebView included in a UIViewController which is a descendant of UINavigationController. It looks like this:
The app is portrait only. When I play the video I want the user to be able to rotate the device and see the video in landscape mode. I use this code to allow it:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
id presentedViewController = [self topMostController];
NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;
if ([className isEqualToString:@"MPInlineVideoFullscreenViewController"] ||
[className isEqualToString:@"MPMoviePlayerViewController"] ||
[className isEqualToString:@"AVFullScreenViewController"]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;
}
- (UIViewController *)topMostController {
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
And then in my UINavigationController (so when the video finishes the view is not presented in landscape but only in portrait):
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
Everything works perfectly:
But then the video is done playing (or the user taps ‘Done’) and the screens return to the underlying view, this is what happens:
As you can see, the navigation bar slips under the status bar. Additionally, I get a lot of auto-layout errors in the logs: http://pastebin.com/09xHzmgJ
Any idea about how to solve this?
I faced this problem yesterday, where @entropid answer worked for iOS 9 and below, but for iOS 10 it didn't (since iOS 10 did actually hide the status bar, where on iOS 9 and below it was just the
UINavigationBar
that changed its frame without hiding the status bar and, thus, it overlapped that bar).Also, subscribing to
MPMoviePlayerControllerDidExitFullScreen
notification didn't work either, sometimes it simply wasn't called (in my particular case, it was because it was a video from aUIWebView
, which used a different class of player which looks similar toMPMoviePlayerController
).So I solved it using a solution like the one @StanislavPankevich suggested, but I subscribed to notifications when a
UIWindow
has become hidden (which can be in several cases, like when a video has finished, but also when aUIActivityViewController
dismisses and other cases) instead ofviewWillLayoutSubviews
. For my particular case (a subclass ofUINavigationController
), methods likeviewDidAppear
,viewWillAppear
, etc. simply weren't being called.viewDidLoad
dealloc
And finally, videoDidExitFullscreen
I used
UIStatusBarAnimationFade
because it looks a lot smoother thanUIStatusBarAnimationNone
, at least from a user perspective.It's very simple, as it says @Stanislav Pankevich, but in
swift 3 version