IOS 8 UIActionSheet игнорирует поддерживаемый контроллер просмотраInterfaceOrientations и shouldAutorotate
У меня есть приложение, которое настроено с помощью файла plist для поддержки книжной, альбомной и альбомной ориентаций (т.е. UISupportedInterfaceOrientations установлен на UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft и UIInterfaceOrientationLandscapeRight). Но я ограничил поддерживаемые ориентации только портретом внутри контроллера представления. Если я представлю UIActionSheet в представлении контроллера представления и затем поверну устройство, UIActionSheet вращается в новой ориентации. Это происходит только на устройствах под управлением iOS 8 (GM Seed).
Я хотел бы, чтобы UIActionSheet следовал правилам содержащего контроллера представления и не вращался. Мысли?
Я не хочу, чтобы это произошло
Пример кода 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;
}
Ответы
Ответ 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;
}
спасибо, что это сработало для меня