I want to only support vertical orientation throughout all the view controllers of my iOS app. However, I embed a YouTube video in one of my view controllers, and when that video is selected to take up the full screen, I want the user to be able to orient his/her phone horizontally so the video expands to take the full screen.
EDIT: I tried using the following code from Autorotate in iOS 6 has strange behaviour:
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return self.fullScreenVideoIsPlaying ?
UIInterfaceOrientationMaskAllButUpsideDown :
UIInterfaceOrientationMaskPortrait;
}
and in my view controller that presents the UIWebView
/YouTube frame, I have this code in my viewDidLoad
:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(windowNowVisible:)
name:UIWindowDidBecomeVisibleNotification
object:self.view.window
];
- (void)windowNowVisible:(NSNotification *)notification
{
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = !(appDelegate.fullScreenVideoIsPlaying);
}
However, when the user presses done on the fullscreen YouTube video, if he/she still has the phone horizontally, then the presenting view controller also stays horizontal (I want the present view controller to be portrait). It's a race on the fullSreenVideoIsPlaying
variable which isn't updating fast enough so that my presenting view controller is portrait.
Any feedback on how to achieve this would be greatly appreciated.
Thanks!
Figured out a solution by molding together a few solutions I've found on StackOverflow.
Instead of using this notification
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(windowNowVisible:)
name:UIWindowDidBecomeVisibleNotification
object:self.view.window
];
I use the following notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
with the implementations
-(void) youTubeStarted:(NSNotification*) notif {
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = YES;
}
-(void) youTubeFinished:(NSNotification*) notif {
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = NO;
}
and in my AppDelegate, I have
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (self.fullScreenVideoIsPlaying) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
and in my view controllers, I have
-(BOOL) shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
I've encountered the very same problem before, and the best solution I could find that worked under iOS 5.x and 6.x was to present the video controller in a modal view.
The modal view is a UINavigationController
that wraps the video controller and responds with UIInterfaceOrientationMaskAll
in supportedInterfaceOrientations
. In the modal view's viewWillAppear:
, I flip fullScreenVideoIsPlaying
to YES
and set it to NO
in viewWillDisappear:
. This arrangement will keep the underlying view controllers in portrait while allowing the modal view to rotate as the user sees fit.