2014-09-13 60 views
23

我有经由plist文件配置成支持肖像的应用程序,景观左和右横向取向(即UISupportedInterfaceOrientations设置为UIInterfaceOrientationPortrait,UIInterfaceOrientationLandscapeLeft,和UIInterfaceOrientationLandscapeRight)。但是我已经将支持的方向限制在视图控制器内部。如果我在视图控制器的视图上显示UIActionSheet,然后旋转设备,UIActionSheet旋转到新的方向。这只发生在运行iOS 8(GM种子)的设备上。iOS 8的UIActionSheet忽略视图控制器supportedInterfaceOrientations和shouldAutorotate

我想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

获悉,UIAlertController iOS中取代UIActionSheet 8

“新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]; 
+5

当然,有一种新的“首选”方式,但为什么只是因为引入了一种新方法而改变/破坏旧的工作功能呢?这种新方式是获得原始行为的唯一方法吗? – Bushrod 2014-09-18 19:04:59

+0

不,因为iOS7用户仍然需要处理旧的警报/工作表。显然是一个需要修复的错误。 – Morrowless 2014-09-25 04:27:29

+2

在iOS7上,旧的UIActionSheet不会出现旋转问题。在iOS7及更旧版本上使用UIActionSheet。在iOS8和更新版本上使用UIAlertController。检查NSClassFromString(@“UIAlertController”)以确定使用哪个代码。 – Awesomeness 2014-10-05 14:13:12

11

我有一个类似的问题与iOS 8,并找到一个解决办法,如果你想与UIAlertView中和UIActionSheet坚持现在可以帮助,而不是迁移到UIAlertController。

我的应用程序允许横向和纵向,但只在选定的视图。大多数时候它只允许肖像。我想让UIAlertView和UIActionSheet只显示肖像(因为它们所在的视图只允许肖像)。

不幸的是,在iOS 8中,警报和操作表现在旋转,忽略窗口根视图控制器的shouldAutorotate方法。即使警报旋转,警报下方的视图和状态栏仍可在肖像中显示。如果警报需要输入,键盘也会保持纵向,所以它确实没有吸引力。

我即将放弃,但终于找到了一些可行的东西,即使它不理想。将其放入您的应用程序委托中,并根据需要进行调整。我期待着更好的解决方案(可能只是使用新的类)。这里的字符串比较显然是蹩脚的,并且这将覆盖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:

+0

这是否会导致App Store因为使用私有类而被拒绝? – sethfri 2014-10-06 19:04:30

+0

如果您担心“_UI ...”,请尝试下面的user3750435的变体。 “使用”类名来确定何时不旋转并不是最安全的事情,但不应该是违规行为,因为它不会调用该类的任何方法/属性。作为另一种选择,您可以将窗口与您自己已知的窗口进行匹配。我的用途是企业,所以没有被拒绝的风险。 – Bushrod 2014-10-07 20:01:29

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; 
} 
+0

是的,这会起作用。谢谢! 我选择使用新的UIAlertController(如果可用)。块的使用相当不错,我很快就会放弃iOS 7的支持。 – Awesomeness 2014-10-05 14:16:22

+2

这将失败,纵向颠倒。 – Vignesh 2014-12-02 06:47:06

+0

如果您想要颠倒支持,请改为返回UIInterfaceOrientationMaskAll。 – 2014-12-10 21:11:55

0

添加到@ user3750435的回答

由于OP已定义了他/她想要的Info.plist中的旋转蒙版,因此我们无需在此重新定义蒙版。UIApplication可以通过 supportedInterfaceOrientationsForWindow:返回给我们那些面具。 (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; 

}

- (NSUInteger)应用

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

:那么,该方法可以这样更简单谢谢这对我有用