10

My iPhone app is a portrait orientation only app and in my app I have a UITableView that has a UIWebView in the first UITableCell. The UIWebView shows an embedded youtube video. When I click on the video to play it enters fullscreen mode. What I need to do is, allow the user to rotate their device and play the video in landscape mode. Then when the video is stopped only allow portrait again. I setup to listen for the notification when the video enters fullscreen and leaves full screen. But I don't know how to programmatically allow the user to rotate the interface orientation.

so basically I have 2 methods called when the notification is passed

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];

-(void)youTubeStarted:(NSNotification *)notification{
    // Entered fullscreen code goes here.
}

-(void)youTubeFinished:(NSNotification *)notification{
    // Left fullscreen code goes here.
}

What would I put in those 2 methods to allow orientation change only during the video playback?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
iRebel_85
  • 769
  • 6
  • 22
  • Be careful, since IOS6 the notification for the 'video done button' seem to be : `UIMoviePlayerControllerWillExitFullscreenNotification` (see: http://stackoverflow.com/a/8554040/1436861 and http://stackoverflow.com/a/12681507/1436861) – Thomas Besnehard Apr 28 '14 at 09:54
  • possible duplicate of [UIMoviePlayerControllerDidEnterFullscreenNotification not work in iOS8](http://stackoverflow.com/questions/25561812/uimovieplayercontrollerdidenterfullscreennotification-not-work-in-ios8) – Thomas Tempelmann Aug 24 '15 at 10:37

3 Answers3

19

I figured it out. In my 2 methods:

-(void)youTubeStarted:(NSNotification *)notification{
   // Entered Fullscreen code goes here..
   AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
   appDelegate.fullScreenVideoIsPlaying = YES;
}

-(void)youTubeFinished:(NSNotification *)notification{
   // Left fullscreen code goes here...
   AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
   appDelegate.fullScreenVideoIsPlaying = NO;

   //CODE BELOW FORCES APP BACK TO PORTRAIT ORIENTATION ONCE YOU LEAVE VIDEO.
   [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
    //present/dismiss viewcontroller in order to activate rotating.
    UIViewController *mVC = [[UIViewController alloc] init];
    [self presentModalViewController:mVC animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

I accessed my App delegate in the above methods by setting the BOOL property of my AppDelegate. Then I called the application method below in my AppDelegate.m:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (self.fullScreenVideoIsPlaying == YES) {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
    if(self.window.rootViewController){
        UIViewController *presentedViewController = [[(UINavigationController  *)self.window.rootViewController viewControllers] lastObject];
        orientations = [presentedViewController supportedInterfaceOrientations];

    }
    return orientations;
}
}

The self.fullScreenVideoIsPlaying is a BOOL that I set as a property in my AppDelegate.h file.

I hope this helps others the 5 hours I lost figuring it out.

iRebel_85
  • 769
  • 6
  • 22
  • Thank you!! I spent several hours searching for an answer to this problem, and your solution was by far the simplest. Much appreciated :) – Steph Sharp Nov 25 '13 at 03:42
  • I have been searching for hours on how to fix my rotation problem. This fixed it; however, I can't seem to get it to disable rotation after video ends. Where did you put the notification call for youTubeFinished? – helloimbarbara Dec 11 '13 at 19:47
  • 1
    Nevermind, I fixed it. I realise my entire app was rotating. To fix this, I just removed the if(self.window.rootViewController) statement in the supportedInterfaceOrientationsForWindow method. Now everything works perfectly. Thanks for posting this! – helloimbarbara Dec 11 '13 at 20:08
  • Hi @brownieface after removing also i am unable to stop the orientaions in my application. And also after completing vedio app still in mode landscape only. it wont change forcefully. Please help me what i am doing wrong – KAREEM MAHAMMED Feb 06 '14 at 11:29
  • How do I fire the 2 methods? Add a target to the WebView when its touched? – jsetting32 Oct 29 '14 at 08:34
  • The 'NSNotificationCenter' calls the two methods. You can see where I set that up in the original question. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil]; And this [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil]; – iRebel_85 Oct 30 '14 at 15:05
  • Crash! Initially when read the line: UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];. I think that am set MFSideMenuContainerViewController as containerview of rootview for window. – Mohd Sadham Jan 21 '15 at 06:41
2

If you only want to support landscape playback in fullscreen. From iOS 8 onwards, video from UIWebView plays inside AVPlayerViewController.

In your AppDelegate check if presenting window contains AVPlayerViewController.

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

    if let w = window, let root = w.rootViewController {

        if root.childViewControllers.first is AVPlayerViewController {  
            return UIInterfaceOrientationMask.allButUpsideDown
        }
    }

    return UIInterfaceOrientationMask.portrait
}
0

You would have a global state variable, probably in your app delegate or wherever you store your variables that should be globally accessible, and then set it to true or false depending on wether the movie player is in fullscreen or not. In the callbacks that are called to rotate the app, you check the state of the variable and depending on that return if the rotation is allowed or not.

JustSid
  • 25,168
  • 7
  • 79
  • 97
  • I probably should have mentioned that I also had a BOOL set for that exact reason but I failed at trying to change if the rotation is allowed or not in the call backs to rotate the app. Would you be able to show me some code that would allow that? – iRebel_85 Jun 19 '13 at 03:06