IOS6 landscape playing embedded youtube video from a uiwebview within an only portrait iPhone app
Asked Answered
P

2

8

I've got an iPhone application with a storyboard,few xib and custom cells.

The application is set as a "portrait" as "supported interface orientation" (i mean everything is display like that). In my custom cells, there is Uiwebview that is linked to a youtube embedded video, when i clicked it the video start to playing, but my problem is that they are always playing in "portrait" mode. I've read lots of things that solve this problem but only in ios5.

Actually : I can identify when the video start or stop playing. I can identify the device orientation. But i can't (I want) switch (Force) orientation from portrait to landscape, or propose this ability if the user change the orientation of his device.

Thanks in advance.

PS : I can display the code for the identifying stuff of the application, if needed.

Patio answered 16/7, 2013 at 15:32 Comment(0)
W
5

I had same problem. My solution is:

1.First of all turn on all orientations in your xcode project:

enter image description here

2.In AppDelegate.m add:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSArray *stackViewControllers = self.navigationController.viewControllers;
    UIViewController *rvc = [stackViewControllers objectAtIndex:stackViewControllers.count - 1];

    if([rvc isKindOfClass:[VideoViewController class]])
    {
        id presentedViewController = [rvc presentedViewController];

        NSString *viewControllerName = NSStringFromClass([presentedViewController class]);
        if([viewControllerName isEqual:@"MPInlineVideoFullscreenViewController"] && [VideoViewController isVideoPlaying]) {
            return UIInterfaceOrientationMaskAll;
        }
    }
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

In above code, everytime system asks for supportedInterfaceOrientationsForWindow you check if current viewController is that where you've put UIWebView with youtube player embedded and also check if video is playing now (namely video is in fullscreen mode).
NOTE: I use UINavigationController, if you don't, you must make some changes to get current viewController.

3.In viewController where I I've put UIWebView for youtube embedded player (In my case it is VideoViewController), in it's header file add method:

+(BOOL)isVideoPlaying;


4.In VideoViewController.m add static variable:

static BOOL _isVideoPlaying = NO;


5.In viewDidLoad add addObserver for notifications, in order to know, when video started to play and willExitPlaying:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerWillExitFullscreen:) name:@"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];


6. Also, add notification selector methods:

-(void)playerStarted:(NSNotification *)notification{
    _isVideoPlaying = YES;
}
-(void)playerWillExitFullscreen:(NSNotification *)notification {
    _isVideoPlaying = NO;

    if([AppUtils iOSVersion] < 6) //For iOS < 6.0, you must manually rotate viewController's view when fullscreen video playing is dismissed.
    {
        if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
        {
            self.navigationController.view.userInteractionEnabled = NO;
            [UIView animateWithDuration:0.5 animations:^{
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft  animated:NO];
                // rotate main view, in this sample the view of navigation controller is the root view in main window
                [self.navigationController.view setTransform: CGAffineTransformMakeRotation(180 * M_PI * 0.5)];
                // set size of view
                [self.navigationController.view setFrame:CGRectMake(0, 0, 320, 960)];
            } completion:^(BOOL finished) {
                self.navigationController.view.userInteractionEnabled = YES;
            }];
        }
    }
}


7.And, add methods in VideoViewController.m:

+(BOOL)isVideoPlaying {
    return _isVideoPlaying;
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    if(!isVideoPlaying) {
        return toInterfaceOrientation != UIInterfaceOrientationLandscapeLeft && toInterfaceOrientation != UIInterfaceOrientationLandscapeRight;
    }
    return YES;
}


All this tricks works well for me, supporting iOS 5 and later.
Hope it works for you!

Wistrup answered 19/7, 2013 at 5:21 Comment(2)
Thanks a lot, it works. I can provide sources for anyone if needed.Patio
@Patio can you send me demo project of this?i getting errors?i don't know how to solve it.Westbrooks
H
24

I took Almas Adilbek's answer (very nicely done!) and boiled it down to its essential component. Just this code alone (added to my app delegate) seems to be getting the desired results for me. Will update if I run into any issues.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

    id presentedViewController = [window.rootViewController presentedViewController];
    NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;

    if (window && [className isEqualToString:@"MPInlineVideoFullscreenViewController"]) {
        return UIInterfaceOrientationMaskAll;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
Had answered 21/8, 2013 at 23:29 Comment(6)
Works fine except when the video is embedded in a modal and there is a little bug when dismissing the video in landscape. If you do so, the interface is then in landscape. To correct it add the following test : [presentedViewController isBeingDismissed] == NOPowel
THx for the answer. But it is not working for me on iOS7. className is alway RootViewController. Any idea ? I'm going to use a 'isPlayingYoubeVideo' flag, but this is not very pretty ...Leroy
On iOS 8 check AVFullScreenViewController instead of MPInlineVideoFullscreenViewControllerRestive
on iOS 8 i am getting nil presentedViewController. Any idea why?Hymn
@Restive your solution helped me...+1 for youHymn
@YestayMuratov any luck with this in Swift?Danella
W
5

I had same problem. My solution is:

1.First of all turn on all orientations in your xcode project:

enter image description here

2.In AppDelegate.m add:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSArray *stackViewControllers = self.navigationController.viewControllers;
    UIViewController *rvc = [stackViewControllers objectAtIndex:stackViewControllers.count - 1];

    if([rvc isKindOfClass:[VideoViewController class]])
    {
        id presentedViewController = [rvc presentedViewController];

        NSString *viewControllerName = NSStringFromClass([presentedViewController class]);
        if([viewControllerName isEqual:@"MPInlineVideoFullscreenViewController"] && [VideoViewController isVideoPlaying]) {
            return UIInterfaceOrientationMaskAll;
        }
    }
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

In above code, everytime system asks for supportedInterfaceOrientationsForWindow you check if current viewController is that where you've put UIWebView with youtube player embedded and also check if video is playing now (namely video is in fullscreen mode).
NOTE: I use UINavigationController, if you don't, you must make some changes to get current viewController.

3.In viewController where I I've put UIWebView for youtube embedded player (In my case it is VideoViewController), in it's header file add method:

+(BOOL)isVideoPlaying;


4.In VideoViewController.m add static variable:

static BOOL _isVideoPlaying = NO;


5.In viewDidLoad add addObserver for notifications, in order to know, when video started to play and willExitPlaying:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerWillExitFullscreen:) name:@"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];


6. Also, add notification selector methods:

-(void)playerStarted:(NSNotification *)notification{
    _isVideoPlaying = YES;
}
-(void)playerWillExitFullscreen:(NSNotification *)notification {
    _isVideoPlaying = NO;

    if([AppUtils iOSVersion] < 6) //For iOS < 6.0, you must manually rotate viewController's view when fullscreen video playing is dismissed.
    {
        if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
        {
            self.navigationController.view.userInteractionEnabled = NO;
            [UIView animateWithDuration:0.5 animations:^{
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft  animated:NO];
                // rotate main view, in this sample the view of navigation controller is the root view in main window
                [self.navigationController.view setTransform: CGAffineTransformMakeRotation(180 * M_PI * 0.5)];
                // set size of view
                [self.navigationController.view setFrame:CGRectMake(0, 0, 320, 960)];
            } completion:^(BOOL finished) {
                self.navigationController.view.userInteractionEnabled = YES;
            }];
        }
    }
}


7.And, add methods in VideoViewController.m:

+(BOOL)isVideoPlaying {
    return _isVideoPlaying;
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    if(!isVideoPlaying) {
        return toInterfaceOrientation != UIInterfaceOrientationLandscapeLeft && toInterfaceOrientation != UIInterfaceOrientationLandscapeRight;
    }
    return YES;
}


All this tricks works well for me, supporting iOS 5 and later.
Hope it works for you!

Wistrup answered 19/7, 2013 at 5:21 Comment(2)
Thanks a lot, it works. I can provide sources for anyone if needed.Patio
@Patio can you send me demo project of this?i getting errors?i don't know how to solve it.Westbrooks

© 2022 - 2024 — McMap. All rights reserved.