iOS 6.0+ autorotation for youtube embedded video
Asked Answered
P

2

8

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!

Payer answered 2/5, 2013 at 20:53 Comment(2)
You may read - buddingdevelopers.com/autorotation-in-ios Autorotation is clearly explained here.Particiaparticipant
possible duplicate: #13581253Contractor
P
21

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;
 }
Payer answered 6/5, 2013 at 0:59 Comment(9)
Just keep in mind that using private notifications (UIMoviePlayerControllerDidEnterFullscreenNotification and UIMoviePlayerControllerWillExitFullscreenNotification) could break in future iOS releases or cause an App Store rejection.Daughterinlaw
Ok thanks! Do you know of any other notification I could use?Payer
Unfortunately the SDK doesn't provide any as of iOS 6.Daughterinlaw
What I ended up doing is returning UIInterfaceOrientationMaskAllButUpsideDown in the delegate method, and then subclassing UITabBarController (my root view controller) to return UIInterfaceOrientationMaskPortrait in -supportedInterfaceOrientations. That way, video can play in landscape, but all the child view controllers of the tab bar controller only support portrait.Phyllisphylloclade
How can i make portrait only?Martens
Sorry my mistake,i want landscape only for youtube player.Martens
How'd you hook up the notifications?Deirdre
Rohan:dude you are my hero...u saved my dayYamamoto
@jszumski's comment makes me nervous, but I have exhausted my search for better solutions.Brotherton
D
6

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.

Daughterinlaw answered 5/5, 2013 at 0:32 Comment(7)
thanks for your response..had a quick follow-up question. Right now, my UIWebView of the youtube video is a small cell (200x100) in the middle of my presenting view controller. When it's selected to play, how do I present the video in a modal view controller? In other words, how do I get a callback that the user pressed the play button in the UIWebView?Payer
The video player that comes from the web view will respect its parent's rotation settings, so you'll have to make your "presenting view controller" a modal view.Daughterinlaw
I understand that the video player will respect its parent's rotation settings; however, my issue is that I don't want the present view controller to be able to rotate horizontally. Only the video player that it presents should be able to rotate horizontallyPayer
Specifically, how do you "present the video controller in a modal view"? Is there a way I can get a pointer to the video controller?Payer
Unfortunately there isn't a way to get a reference to the web view's MPMoviePlayerController, I meant controller as in the view controller containing your 200x100 web view. You could present a full-size UIWebView in a modal controller and have it auto play (mediaPlaybackRequiresUserAction = NO).Daughterinlaw
thanks this is starting to make sense to me. do you have any code that shows how to do this? My issue specifically is, how do I present a modal view that is a uinavigationcontroller that wraps the video controller? Since the youtube video is in a webview and I don't have any callbacks, I don't know when the user touches play in the webview. Also, the uiwebview of the embedded youtube video is in a uicollectionviewcell (not sure if that's relevant)Payer
Thanks for your help, but I've found a new solution which I posted herePayer

© 2022 - 2024 — McMap. All rights reserved.