Lee
Lee

Reputation: 149

YouTube Embedded Player Orientation

Firstly kudos to Google Developers for making it so easy to add the embedded player to an iOS project. My question is how to change orientation.

Originally I had set my project to Portrait only in the General settings. This worked for all viewcontrollers, however it also worked on the YouTube player. The video plays as expected, however when I rotate the phone, the video stays in portrait.

If I go back to General settings and also set it to landscape, then the player rotates correctly (but then so do all the viewcontrollers in the project).

I have read other answers here about how to release orientation for 1 specific controller, but I only want rotate to work when watching a video full-screen. If the user decides just to watch the video in the UIView that I created then I want orientation to be locked.

I have followed the instructions at https://developers.google.com/youtube/v3/guides/ios_youtube_helper so the only code that I needed to add beyond that was:

[self.playerView loadWithVideoId:videoSourceID];

Like I said, there is nothing wrong with the video playing, nothing wrong with making the vide full-screen, it's only the orientation that concerns me.

TLDR: So basically, I only want 'rotation to landscape' unlocked if the user is watching a YouTube video full-screen, everything else in the app should be locked to portrait (including the viewcontroller where the UIView displays the windowed video). Thanks for looking!

Upvotes: 1

Views: 1729

Answers (2)

Dmytro Shvetsov
Dmytro Shvetsov

Reputation: 1006

Swift 3.0

class AppDelegate
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        guard UIApplication.currentVC.isMovie else { return application.supportedInterfaceOrientations(for: window) }
        return UIInterfaceOrientationMask.allButUpsideDown
    }
}


extension UIApplication {
    struct currentVC {
        static var isMovie: Bool {
            guard let presentedViewController = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController else { return false }

            let className = String(describing: type(of: presentedViewController))

            return ["MPInlineVideoFullscreenViewController",
                    "MPMoviePlayerViewController",
                    "AVFullScreenViewController"].contains(className)
        }
    }
}


import AVKit
extension AVPlayerViewController {
    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        UIDevice.current.setValue(UIInterfaceOrientationMask.portrait.rawValue, forKey: "orientation")
    }
}

Upvotes: 0

metronic
metronic

Reputation: 455

Paste this code on your AppDelegate.m:

- (UIViewController*)topViewController {
return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
// Handling UITabBarController
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
    UITabBarController* tabBarController = (UITabBarController*)rootViewController;
    return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
}
// Handling UINavigationController
else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController* navigationController = (UINavigationController*)rootViewController;
    return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
}
// Handling Modal views
else if (rootViewController.presentedViewController) {
    UIViewController* presentedViewController = rootViewController.presentedViewController;
    return [self topViewControllerWithRootViewController:presentedViewController];
}
// Handling UIViewController's added as subviews to some other views.
else 
{
    for (UIView *view in [rootViewController.view subviews])
    {
        id subViewController = [view nextResponder];    // Key property which most of us are unaware of / rarely use.
        if ( subViewController && [subViewController isKindOfClass:[UIViewController class]])
        {
            return [self topViewControllerWithRootViewController:subViewController];
        }
    }
    return rootViewController;
    }
}

On the following method you can decide the orientation for every UIViewController. Put it on you AppDelegate.m

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

id presentedViewController = [self topViewController];
NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;

if (window && [className isEqualToString:@"FullScreenViewController"]) { //FullScreenViewController should support all orientations. Put the exact name of the viewcontroller displayed when the video is fullscreen

    return UIInterfaceOrientationMaskAll;
} else {
    return UIInterfaceOrientationMaskPortrait; //Every other viewcontroller will support portrait only
}
}

You have to detect the exact name of the UIViewController displayed when the video is fullscreen. You have to find it on the stack trace, and put its name instead of "FullScreenViewController" which I wrote as an example

Upvotes: 1

Related Questions