web-dev-qa-db-ja.com

iOS 8 UIActionSheetは、View ControllerのsupportedInterfaceOrientationsを無視し、shouldAutorotate

ポートレート、ランドスケープ左、ランドスケープ右の方向をサポートするようにplistファイルを介して構成されたアプリケーションがあります(つまり、UISupportedInterfaceOrientationsはUIInterfaceOrientationPortrait、UIInterfaceOrientationLandscapeLeft、およびUIInterfaceOrientationLandscapeRightに設定されています)。ただし、サポートされている向きは、ビューコントローラー内の縦向きに限定しています。ビューコントローラのビューにUIActionSheetを表示してからデバイスを回転させると、UIActionSheetは新しい方向に回転します。これは、iOS 8(GMシード)を実行しているデバイスでのみ発生します。

UIActionSheetが、含まれているView Controllerのルールに従い、回転しないようにしたいと思います。考え?

私はこれが起こらないようにしたい: screenshot

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;
}
24
Awesomeness

IOS8ではUIAlertControllerがUIActionSheetに置き換わることが通知されました。

「新しいUIAlertControllerクラスは、アプリでアラートを表示するための推奨される方法として、UIActionSheetクラスとUIAlertViewクラスに置き換わるものです。」

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
Awesomeness

これは、彼の回避策を使用してUIActionSheetでいくつかの問題が発生したため、いくつかの変更を加えたBusrodのソリューションに基づく私の回避策です。

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

IOS 8でも同様の問題が発生し、UIAlertControllerに移行する代わりに、今のところUIAlertViewとUIActionSheetを使い続けたい場合に役立つ回避策を見つけました。

私のアプリでは横向きと縦向きが許可されていますが、一部のビューでのみ使用できます。ほとんどの場合、ポートレートのみが許可されます。 UIAlertViewとUIActionSheetをPortraitのみに表示したい(それらが存在するビューではPortraitのみが許可されているため)。

残念ながら、iOS 8では、ウィンドウのルートビューコントローラーのshouldAutorotateメソッドを無視して、アラートとアクションシートが回転するようになりました。アラートが回転しても、アラートの下のビューとステータスバーはPortraitに表示されたままになります。アラートが入力を受け取る場合、キーボードも縦向きのままなので、本当に魅力的ではありません。

私はあきらめようとしていましたが、それが理想的でなくても、最終的にはうまくいくものを見つけました。これをアプリデリゲートに入れ、必要に応じて適応させます。私はより良い解決策を楽しみにしています(おそらく新しいクラスを使用するだけです)。ここでの文字列の比較は明らかに不十分であり、これは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:

11
Bushrod

@ user3750435の回答に追加

OPはInfo.plistで必要な回転マスクを定義しているため、ここでマスクを再定義する必要はありません。 IApplication は、 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];
}
0
Ayush Goel

-(NSUInteger)アプリケーション:(UIApplication *)アプリケーション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