iOS 8 UIActionSheet ignores view controller supportedInterfaceOrientations and shouldAutorotate

Here is my workaround based on the solution from Busrod with some modifications because I had some problems in UIActionSheet using his workaround:

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIViewController *presentedViewController = window.rootViewController.presentedViewController;
    if (presentedViewController) {
        if ([presentedViewController isKindOfClass:[UIActivityViewController class]] || [presentedViewController isKindOfClass:[UIAlertController class]]) {
            return UIInterfaceOrientationMaskPortrait;
        }
    }
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

I had a similar problem with iOS 8 and found a workaround that may help if you want to stick with UIAlertView and UIActionSheet for now, instead of migrating to UIAlertController.

My app allows Landscape and Portrait, but only on select views. Most of the time it only allows Portrait. I want UIAlertView and UIActionSheet to appear only Portrait (because the views they are on only allow Portrait).

Unfortunately, with iOS 8 the alerts and action sheets now rotate, ignoring the shouldAutorotate method of the window's root view controller. The view and status bar underneath the alert stay visible in Portrait even if the alert rotates. If the alert takes an input, the keyboard also stays Portrait, so it is really unattractive.

I was about to give up, but finally found something that works, even if it is not ideal. Put this in your app delegate, and adapt as needed. I'm looking forward to a better solution (probably just using the new classes). String comparison here is obviously lame, and this will override whatever you have set as supported orientation in Info.plist. At least it is something to go on...

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSString *viewControllerClassName = [NSString stringWithUTF8String:object_getClassName(window.rootViewController)];
    if ([viewControllerClassName isEqualToString:@"_UIAlertShimPresentingViewController"])   {
        return UIInterfaceOrientationMaskPortrait;
    }
    else {
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
    }
}

Read more about this delegate here:

https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:supportedInterfaceOrientationsForWindow:


Was informed that UIAlertController replaces UIActionSheet in iOS 8.

"The new UIAlertController class replaces the UIActionSheet and UIAlertView classes as the preferred way to display alerts in your app."

https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html

UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"hi"
                                                                          message:nil
                                                                   preferredStyle:UIAlertControllerStyleActionSheet];

[alertController addAction:[UIAlertAction actionWithTitle:@"Open"
                                                  style:UIAlertActionStyleDefault
                                                handler:^(UIAlertAction *action) {
                                                   // open something
                                                }]];

[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
                                                  style:UIAlertActionStyleCancel
                                                handler:nil]];

[self presentViewController:alertController animated:YES completion:nil];