Reputation: 3063
My app consist a functionality of playing videos both in landscape and portrait mode.videos can be youtube also everything was working fine till iOS 7 but now youtube videos are not working in landscape mode on iOS 8.
my code:
- (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;
}
Everything was working fine till iOS 7 but stop working on iOS 8. Any help appreciated
Upvotes: 5
Views: 8099
Reputation: 4471
Here is Swift 3 version for iOS 10.1. I've modified Anthony Persaud answer here. To check if presentedController.isKind(of: MPMoviePlayerViewController.self)
, you'll need 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
}
Upvotes: 0
Reputation: 3063
Well its sometimes silly to answer your own question but its good to help others who are facing the same problem.
in iOS 8 instead of checking for MPInlineVideoFullscreenViewController we need to check for AVFullScreenViewController. So below is the complete method for all iOS versions i.e 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's presented from the top?
} else if ([[nc.topViewController presentedViewController]
isKindOfClass:[MPMoviePlayerViewController class]]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
}
return UIInterfaceOrientationMaskPortrait;
}
Update : Works in iOS 9 as well
Upvotes: 14
Reputation: 1203
This is a solution in Swift tested on iOS7 and iOS8. You have to 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);
}
Upvotes: 1
Reputation: 1186
Update:
One thing to add if you notice your status bar breaking after you come back to your controller from a landscape video is to set the status bar as not hidden to false in viewWillLayoutSubviews
.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: .None)
}
For those in Swift, a few additional notes. This method (application:supportedInterfaceOrientationsForWindow
) should be in your AppDelegate class or whatever you've set to @UIApplicationMain
. In order to have access to the MPMoviePlayerViewController
class, you must remember to import MoviePlayer
.
Second, the UIInterfaceOrientationMask
value is not compatible with the Swift version of the delegate by itself, so you need to access rawValue
and transform the resulting Uint
into an Int
. Here is the Swift solution for those in need.
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)
}
Upvotes: 3
Reputation: 7251
I could not detect the AVFullScreenViewController
in my app on iOS 8 Golden Master, but finding 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"];
});
}
}
Upvotes: 0
Reputation: 404
I have similar code in my app, which also broke in iOS8.
I just wanted to post my version of this fix in case it helps anyone.
The main difference is, i'm only checking against the top most presented controller.
I think this makes more sense than the nested conditionals trying to figure out what kind of vc is presenting another vc.
Anyway, I've got this in my app delegate, and it's working great 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"]
);
}
Upvotes: 5