Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 UIActionSheet ignores view controller supportedInterfaceOrientations and shouldAutorotate

Tags:

I have an application that is configured via the plist file to support portrait, landscape left, and landscape right orientations (i.e. UISupportedInterfaceOrientations is set to UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, and UIInterfaceOrientationLandscapeRight). But I've limited the supported orientations to just portrait inside of a view controller. If I present a UIActionSheet on the view controller's view and then rotate the device, the UIActionSheet rotates to the new orientation. This only happens on devices running iOS 8 (GM Seed).

I would like the UIActionSheet to follow the rules of the containing view controller and not rotate. Thoughts?

I don't want this to happen: screenshot

UIViewController Sample Code:

- (IBAction)onTouch:(id)sender {     UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"hi"                                                        delegate:nil                                               cancelButtonTitle:@"Cancel"                                          destructiveButtonTitle:nil                                               otherButtonTitles:@"Open", nil];      [actionSheet showInView:self.view]; }  #pragma mark - Rotation methods  - (BOOL)shouldAutorotate {     return NO; }  - (NSUInteger)supportedInterfaceOrientations {     return UIInterfaceOrientationMaskPortrait; } 
like image 318
Awesomeness Avatar asked Sep 13 '14 02:09

Awesomeness


2 Answers

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; } 
like image 57
StuckOverFlow Avatar answered Sep 25 '22 03:09

StuckOverFlow


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:

like image 43
Bushrod Avatar answered Sep 25 '22 03:09

Bushrod