Youtubevideo不能在iOS 8中以横向模式播放

我的应用程序包括在横向和纵向模式下播放video的function。video可以是YouTube也一切工作正常,直到iOS 7,但现在YouTubevideo不能在iOS 8的横向模式下工作。

我的代码:

- (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's presented from the top? } else if ([[nc.topViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; } } } return UIInterfaceOrientationMaskPortrait; } 

一切工作正常,直到iOS 7,但停止在iOS 8上工作。任何帮助表示赞赏

那么它有时很愚蠢的回答你自己的问题,但它有助于帮助那些面临同样问题的人。

在iOS 8中,而不是检查MPInlineVideoFullscreenViewController,我们需要检查AVFullScreenViewController。 所以下面是所有iOS版本,即iOS 8和更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's presented from the top? } else if ([[nc.topViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]]) { return UIInterfaceOrientationMaskAllButUpsideDown; } } } return UIInterfaceOrientationMaskPortrait; } 

更新:也适用于iOS 9

我在我的应用程序中有类似的代码,这也在iOS8中打破。

我只是想发布我的这个修复版本的情况下,以帮助任何人。

主要的区别是,我只是检查最顶级的控制器。

我认为这比嵌套条件更有意义,试图找出什么样的VC呈现另一个VC。

无论如何,我已经在我的应用程序代表中获得了这个,而且它在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"] ); } 

更新 :如果在从横向video回到控制器后注意到状态栏断裂,则添加一件事是在viewWillLayoutSubviews中将状态栏设置为不隐藏为false。

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

对于那些在斯威夫特,另外几个笔记。 这个方法( application:supportedInterfaceOrientationsForWindow )应该在你的AppDelegate类中,或者你已经设置的任何@UIApplicationMain 。 为了有权访问MPMoviePlayerViewController类,您必须记得import MoviePlayer

其次, UIInterfaceOrientationMask值与委托的Swift版本本身不兼容,因此您需要访问rawValue并将生成的Uint转换为Int 。 这是需要帮助的Swift解决scheme。

  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) } 

这是在iOS7和iOS8上testingSwift的解决scheme。 您必须将此方法添加到您的AppDelegate类。

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); } 

我无法在iOS 8 Golden Master上的应用程序中检测到AVFullScreenViewController ,但是findAVPlayerViewAVFullScreenViewController

的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"]; }); } } 

这里是iOS 10.1的Swift 3版本。 我在这里修改了Anthony Persaud的答案。 要检查if presentedController.isKind(of: MPMoviePlayerViewController.self) ,您需要在顶部import MediaPlayer

 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 }