Подтвердить что ты не робот

IOS 8 UIActionSheet игнорирует поддерживаемый контроллер просмотраInterfaceOrientations и shouldAutorotate

У меня есть приложение, которое настроено с помощью файла plist для поддержки книжной, альбомной и альбомной ориентаций (т.е. UISupportedInterfaceOrientations установлен на UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft и UIInterfaceOrientationLandscapeRight). Но я ограничил поддерживаемые ориентации только портретом внутри контроллера представления. Если я представлю UIActionSheet в представлении контроллера представления и затем поверну устройство, UIActionSheet вращается в новой ориентации. Это происходит только на устройствах под управлением iOS 8 (GM Seed).

Я хотел бы, чтобы UIActionSheet следовал правилам содержащего контроллера представления и не вращался. Мысли?

Я не хочу, чтобы это произошло 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;
}
4b9b3361

Ответ 1

Было сообщено, что UIAlertController заменяет UIActionSheet в iOS 8.

"Новый класс 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];

Ответ 2

Вот мое решение на основе решения от 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;
}

Ответ 3

У меня была аналогичная проблема с iOS 8 и нашел обходное решение, которое может помочь, если вы хотите придерживаться UIAlertView и UIActionSheet, вместо того, чтобы переходить на UIAlertController.

Мое приложение позволяет использовать Пейзаж и Портрет, но только для избранных видов. Большую часть времени он позволяет только портрет. Я хочу, чтобы UIAlertView и UIActionSheet отображались только в портрете (поскольку в представлениях, на которых они находятся, разрешено только портрет).

К сожалению, с iOS 8 предупреждения и панели действий теперь вращаются, игнорируя метод toAutorotate контроллера корневого окна. Строка представления и состояния под предупреждением остается видимым в "Портрет", даже если предупреждение вращается. Если предупреждение принимает ввод, клавиатура также остается в портрете, поэтому она действительно непривлекательна.

Я собирался сдаться, но, наконец, нашел что-то, что работает, даже если оно не идеально. Поместите это в свой делегат приложения и при необходимости адаптируйте. Я с нетерпением жду лучшего решения (возможно, просто используя новые классы). Сравнение строк здесь явно хромает, и это переопределит все, что вы установили в качестве поддерживаемой ориентации в 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:

Ответ 4

Добавление в @user3750435 ответ

Поскольку ОП определил маски вращения, которые он/она хочет в 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];
}

Ответ 5

Приложение

- (NSUInteger): приложение (UIApplication *) поддерживаетсяInterfaceOrientationsForWindow: (UIWindow *) окно {

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

}

спасибо, что это сработало для меня