Youtube video not playing in landscape mode in iOS 8

My application consists of video playback functionality in both landscape and portrait modes. The video can be youtube, and everything works fine until iOS 7, but now YouTube videos don't work in landscape mode on iOS 8.

my code is:

- (NSUInteger)application:(UIApplication *)applicationsupportedInterfaceOrientationsForWindow:(UIWindow *)window { if ([[window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] || [[window.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"MPInlineVideoFullscreenViewController")]) { return UIInterfaceOrientationMaskAllButUpsideDown; } else { if ([[window.rootViewController presentedViewController] isKindOfClass:[UINavigationController class]]) { // look for it inside UINavigationController UINavigationController *nc = (UINavigationController *)[window.rootViewController presentedViewController]; // is at the top? if ([nc.topViewController isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; // or it presented from the top? } else if ([[nc.topViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; } } } return UIInterfaceOrientationMaskPortrait; } 

Everything worked fine until iOS 7, but stopped working on iOS 8. Any help appreciated

+5
source share
6 answers

Well, it’s sometimes stupid to answer your own question, but it’s useful to help others who are faced with the same problem.

in iOS 8, instead of checking on MPInlineVideoFullscreenViewController we need to check AVFullScreenViewController. So, below is the full method for all versions of iOS ie iOS 8 and less.

  - (NSUInteger)application:(UIApplication *)applicationsupportedInterfaceOrientationsForWindow:(UIWindow *)window { if ([[window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] || [[window.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"MPInlineVideoFullscreenViewController")] || [[window.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"AVFullScreenViewController")]) { return UIInterfaceOrientationMaskAllButUpsideDown; }else { if ([[window.rootViewController presentedViewController] isKindOfClass:[UINavigationController class]]) { // look for it inside UINavigationController UINavigationController *nc = (UINavigationController *)[window.rootViewController presentedViewController]; // is at the top? if ([nc.topViewController isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; // or it presented from the top? } else if ([[nc.topViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; } } } return UIInterfaceOrientationMaskPortrait; } 

Update: Works in iOS 9 as well

+14
source

I have similar code in my application that also broke in iOS8.

I just wanted to publish my version of this fix if it helps someone.

The main difference is that I only check the top most represented controller.

I think this makes more sense than nested conditional expressions trying to figure out which vc the other vc represents.

In any case, I have this in my application, and it works fine in 8.

 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { id presentedViewController = [self topMostController]; if ( [self vcIsVideoPlayer:presentedViewController] ) { return UIInterfaceOrientationMaskAll; } else { return UIInterfaceOrientationMaskPortrait; } } - (UIViewController*) topMostController { UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } return topController; } - (BOOL) vcIsVideoPlayer:(UIViewController *)vc { NSString *className = vc ? NSStringFromClass([vc class]) : nil; return ( [className isEqualToString:@"MPInlineVideoFullscreenViewController"] || [className isEqualToString:@"MPMoviePlayerViewController"] || [className isEqualToString:@"AVFullScreenViewController"] ); } 
+5
source

Update : One thing to add if you notice that your status bar is interrupted after you return to the controller from the landscape video, you need to set the status bar as not hidden in false in viewWillLayoutSubviews .

  override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: .None) } 

For those in Swift, a few extra notes. This method ( application:supportedInterfaceOrientationsForWindow ) should be in your AppDelegate class or in what you set in @UIApplicationMain . To access the MPMoviePlayerViewController class, you must remember import MoviePlayer .

Secondly, the UIInterfaceOrientationMask value UIInterfaceOrientationMask incompatible with the Swift delegate version, so you need to access rawValue and convert the resulting Uint to Int . Here is a Swift solution for those who need it.

  func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int { var orientation = UIInterfaceOrientationMask.Portrait if let presentedController = window.rootViewController?.presentedViewController { //check for the controllers if presentedController is MPMoviePlayerViewController || presentedController.isKindOfClass( NSClassFromString("AVFullScreenViewController").self ) || presentedController.isKindOfClass( NSClassFromString("MPInlineVideoFullscreenViewController").self ) { orientation = .AllButUpsideDown } //otherwise, we may be inside a Nav. //safely get the nav controller otherwise ignore this block else if let navController = presentedController as? UINavigationController { if navController.topViewController is MPMoviePlayerViewController || navController.topViewController.isKindOfClass( NSClassFromString("AVFullScreenViewController").self ) || navController.topViewController.isKindOfClass( NSClassFromString("MPInlineVideoFullscreenViewController").self ) { orientation = .AllButUpsideDown } } } return Int(orientation.rawValue) } 
+3
source

This is a solution in Swift, tested on iOS7 and iOS8. You must add this method to your AppDelegate class.

AppDelegate.swift

 func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int { var topController = UIApplication.sharedApplication().keyWindow?.rootViewController if (topController != nil) { while ((topController!.presentedViewController) != nil) { topController = topController!.presentedViewController; } if (topController != nil && (topController!.className == "AVFullScreenViewController" || topController!.className == "MPFullScreenTransitionViewController")) { return Int(UIInterfaceOrientationMask.All.rawValue); } } return Int(UIInterfaceOrientationMask.Portrait.rawValue); } 
+1
source

I could not detect AVFullScreenViewController in my iOS 8 Golden Master application, but searching for AVPlayerView does the trick.

UIViewController + VideoAutorotate.h

 #import <UIKit/UIKit.h> @interface UIViewController (VideoAutorotate) @end 

UIViewController + VideoAutorotate.m

 #import "UIViewController+VideoAutorotate.h" BOOL testAnyViewRecursively(UIView *view, BOOL (^test)(UIView *view)) { if (test(view)) { return YES; } else { for (UIView *subview in view.subviews) { if (testAnyViewRecursively(subview, test)) { return YES; } } } return NO; } @implementation UIViewController (VideoAutorotate) -(BOOL)shouldAutorotate { if (UI_PAD) { return YES; } else { // iOS 6: MPInlineVideoFullscreenViewController in iOS 6 doesn't seem to override this method to return YES. if ([NSStringFromClass([self class]) isEqual:@"MPInlineVideoFullscreenViewController"]) { return YES; } // iOS 8: return testAnyViewRecursively(self.view, ^BOOL(UIView *view) { return [NSStringFromClass([view class]) isEqual:@"AVPlayerView"]; }); } } 
0
source

Here is the Swift 3 version for iOS 10.1. I changed Anthony Perso's answer. To check if presentedController.isKind(of: MPMoviePlayerViewController.self) , you need to import MediaPlayer at the top.

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if let presentedController = window?.rootViewController?.presentedViewController, let avFullScreen = NSClassFromString("AVFullScreenViewController").self, let mpInlineVideoFullscreen = NSClassFromString("MPInlineVideoFullscreenViewController").self { if presentedController.isKind(of: MPMoviePlayerViewController.self) || presentedController.isKind(of: avFullScreen) || presentedController.isKind(of: mpInlineVideoFullscreen) { return UIInterfaceOrientationMask.allButUpsideDown } } return UIInterfaceOrientationMask.portrait } 
0
source

Source: https://habr.com/ru/post/1203111/


All Articles