Hallo,
I have a simple application, which does contain UITabBarController with two UIViewControllers. Both UIViewControllers are portrait only (no rotation allowed).
I have a very similar situation. My app is portrait-only. But I need to show full-screen videos in any orientation, and then get back to the portrait orientation, after the user quits full-screen mode.
Split's method doesn't work for me, because I would like to let user watch the video in fullscreen and embedded, and switch between modes, not loosing the play position, and without any pauses.
I found this workaround:
First, I have a root UINavigationController subclass, that receives all messages regarding rotation.
I forbid the rotation in this controller with:
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation {
return (UIInterfaceOrientationPortrait == toInterfaceOrientation);
}
I am overriding the
- (id) initWithRootViewController:(UIViewController *)rootViewController; method.
Adding the support for device orientation modifications:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil];
Now I have a handler receivedRotate: - that catches all the device rotations in spite of not auto-rotating to any orientations except portrait:
- (void) receivedRotate:(NSNotification*) notify {
if(isVideoFullscreen) {
UIDeviceOrientation toInterfaceOrientation = [[UIDevice currentDevice] orientation];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:2];
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft){
self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
self.view.bounds = CGRectMake(0, 0, 1024, 768);
} else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
self.view.bounds = CGRectMake(0, 0, 1024, 768);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
self.view.transform = CGAffineTransformMakeRotation(M_PI);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortrait) {
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
}
[UIView commitAnimations];
}
}
I just check the rotations of the device, and rotate my view accordingly.
Then - how do the root controller knows, when the video is fullscreen? Just add two other message handlers to the init:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
And the handlers themselves:
- (void) willEnterFullscreen: (NSNotification *) notify {
isVideoFullscreen = YES;
}
- (void) willExitFullscreen: (NSNotification *) notify {
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
isVideoFullscreen = NO;
}
When exiting fullscreen - we restore the portrait orientation. So, this works for me, hope it will help someone.