iOS 8 UIActionSheet忽略视图控制器supportedInterfaceOrientations和shouldAutorotate

时间:2014-09-13 02:01:19

标签: ios rotation orientation ios8 uiactionsheet

我有一个通过plist文件配置的应用程序,以支持纵向,横向左和横向右方向(即UISupportedInterfaceOrientations设置为UIInterfaceOrientationPortrait,UIInterfaceOrientationLandscapeLeft和UIInterfaceOrientationLandscapeRight)。但是我将支持的方向限制在视图控制器内部。如果我在视图控制器的视图上显示UIActionSheet然后旋转设备,则UIActionSheet将旋转到新方向。这只发生在运行iOS 8(GM Seed)的设备上。

我希望UIActionSheet遵循包含视图控制器的规则而不是旋转。想法?

我不希望这种情况发生: screenshot http://oi58.tinypic.com/20tgto2.jpg

UIViewController示例代码:

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

5 个答案:

答案 0 :(得分:21)

以下是基于Busrod解决方案的解决方法,并进行了一些修改,因为我在使用他的解决方法时在UIActionSheet中遇到了一些问题:

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

答案 1 :(得分:11)

我在iOS 8中遇到了类似的问题,如果您现在想要坚持使用UIAlertView和UIActionSheet,而不是迁移到UIAlertController,我们会找到一个可能有用的解决方法。

我的应用程序允许横向和纵向,但仅限于选择视图。大多数时候它只允许肖像。我希望UIAlertView和UIActionSheet只显示Portrait(因为它们所在的视图只允许使用Portrait)。

不幸的是,在iOS 8中,警报和操作表现在会旋转,忽略窗口根视图控制器的shouldAutorotate方法。即使警报旋转,警报下方的视图和状态栏也会在纵向中保持可见状态。如果警报接受输入,键盘也会保持纵向,因此它实际上没有吸引力。

我正要放弃,但最后发现一些有效的东西,即使它不理想。将其放入您的app委托中,并根据需要进行调整。我期待更好的解决方案(可能只是使用新类)。这里的字符串比较显然很蹩脚,这将覆盖您在Info.plist中设置为支持方向的任何内容。至少它还有待继续......

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

在此处阅读有关此代表的更多信息:

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

答案 2 :(得分:5)

获悉UIAlertController取代了iOS 8中的UIActionSheet。

"新的UIAlertController类将UIActionSheet和U​​IAlertView类替换为在您的应用中显示警报的首选方式。"

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];

答案 3 :(得分:0)

添加到@ user3750435的回答

由于OP在Info.plist中定义了他/她想要的旋转蒙版,我们不需要在这里重新定义蒙版。 UIApplication可以通过我们返回这些面具 supportedInterfaceOrientationsForWindow:。因此,该方法可以更简单:

-(NSUInteger)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 [application supportedInterfaceOrientationsForWindow:window];
}

答案 4 :(得分:0)

- (NSUInteger)应用程序:(UIApplication *)应用程序supportedInterfaceOrientationsForWindow:(UIWindow *)窗口 {

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

}

感谢这对我有用