Запуск в портретную ориентацию с домашнего экрана iPhone 6 Plus в альбомной ориентации приводит к неправильной ориентации

Фактическое название для этого вопроса длиннее, чем я могу поместиться:

Запуск приложения, чей контроллер корневого представления поддерживает только портретную ориентацию, но в противном случае поддерживает ландшафтные ориентации на iPhone 6 Plus, в то время как домашний экран находится в альбомной ориентации, приводит к состоянию неопределенности, когда окно приложения находится в альбомной ориентации, но устройство находится в портретной ориентации.

Короче говоря, это выглядит так:

sQ1o7.jpg

Когда он должен выглядеть следующим образом:

msCDu.jpg

Шаги по воспроизведению:

  • iPhone 6 Plus работает под управлением iOS 8.0.

  • Приложение, чей plist поддерживает ориентацию "все-но-портрет-вверх-вниз".

  • Контроллер корневого представления приложения является UITabBarController.

  • Все, контроллер панели вкладок и все его дочерние контроллеры дочерних представлений возвращают UIInterfaceOrientationMaskPortrait из supportedInterfaceOrientations.

  • На начальном экране iOS.

  • Поворот в альбомную ориентацию (требуется iPhone 6 Plus).

  • Холодный запуск приложения.

  • Результат: разбитые ориентации интерфейса.

Я не могу думать о другом способе обеспечения ориентации на портреты, кроме как отключить ландшафт вообще, чего я не могу сделать: нашим диспетчерам модального просмотра веб-браузера нужен пейзаж.

Я даже попробовал подклассифицировать UITabBarController и переопределить supportInterfaceOrientations, чтобы вернуть маску только для портрета, но это (даже со всеми другими шагами выше) не устранило проблему.


Здесь ссылка на пример проекта, показывающий ошибку.


Ответ 1

Это похоже на ошибку в iOS 8 при использовании UITabBarController в качестве контроллера корневого представления. Обходным путем является использование в основном контроллера валиков UIViewController в качестве контроллера корневого представления. Этот контроллер просмотра ванили будет служить в качестве родительского контроллера представления вашего контроллера панели вкладок:

///------------------------
/// Portrait-Only Container
///------------------------

@interface PortraitOnlyContainerViewController : UIViewController

@end

@implementation PortraitOnlyContainerViewController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

@end

// Elsewhere, in app did finish launching ...

PortraitOnlyContainerViewController *container = nil;

container = [[PortraitOnlyContainerViewController alloc] 
              initWithNibName:nil 
              bundle:nil];

[container addChildViewController:self.tabBarController];
self.tabBarController.view.frame = container.view.bounds;
[container.view addSubview:self.tabBarController.view];
[self.tabBarController didMoveToParentViewController:container];

[self.window setRootViewController:container];

Ответ 2

У меня была такая же проблема при запуске нашего приложения в ландшафте на iPhone 6 Plus.

Наше исправление заключалось в том, чтобы удалить ориентированные на ландшафт ориентации интерфейса из plist через настройки проекта:

Removed landscape orientation

и реализовать приложение: supportedInterfaceOrientationsForWindow: в делетете приложения:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

По-видимому, информация в вашем plist заключается в том, чтобы указать, к каким ориентирам ваше приложение разрешено запускать.

Ответ 3

Настройка statusBarOrientation для UIApplication, похоже, работает для меня. Я поместил его в метод application:didFinishLaunchingWithOptions: в делегате приложения.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    application.statusBarOrientation = UIInterfaceOrientationPortrait;

    // the rest of the method
}

Ответ 4

У меня была очень похожая проблема. Я хотел заставить режим портрет повсюду, кроме воспроизведения видео.

Что я сделал:

1), чтобы ориентация приложения была в портрете в AppDelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if ([window.rootViewController.presentedViewController isKindOfClass:[MPMoviePlayerViewController class]])
    {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

2) запуск пустого диспетчера модального вида зафиксировал проблему в моем случае. Я запускаю его в viewDidLoad первого контроллера представлений, который находится в корне моего навигационного контроллера (первый контроллер видимости, видимый после запуска приложения):

- (void)showAndHideNamelessViewControllerToFixOrientation {
    UIViewController* viewController = [[UIViewController alloc] init];
    [self presentViewController:viewController animated:NO completion:nil];
    [viewController dismissViewControllerAnimated:NO completion:nil];
}

Ответ 5

Пожалуйста, попробуйте следующий код. Вероятно, эта проблема вызвана размером keywindow при запуске ландшафта.

// in application:didFinishLaunchingWithOptions: ...

self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]]; //<- ADD!!

Ответ 6

Мне не повезло обходное решение Джареда с использованием универсального контроллера контейнера. Я уже подклассифицировал контроллер панели вкладок с поддержкойInterfaceOrientations и не повезло. Независимо от ориентации 6+ после запуска окно панели вкладок сообщает frame = (0 0; 736 414)

До сих пор единственным обходным решением, которое я нашел, является принудительное форматирование окна после makeKeyAndVisible

[self.window makeKeyAndVisible]; self.window.frame = CGRectMake(0, 0, MIN(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)), MAX(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)));

Ответ 7

Я хочу, чтобы мое приложение открывалось в ландшафтном режиме (и не демонстрирует проблему, описанную выше на iPhone 6 Plus), поэтому я установил Landscape (left home button) и Landscape (right home button) как единственные ориентации, разрешенные в моем файле PLIST приложения. Это устраняет проблему ориентации, когда открывается мое приложение. Тем не менее, мне нужно, чтобы приложение поддерживало портретный режим для одного вида только с тех пор, как я показываю UIImagePickerController в своем приложении, которое Apple требуется для показа в портретном режиме на iPhone.

Я мог поддерживать портрет только для этого одного вида, сохраняя открытие своего приложения в ландшафтном режиме, включив в AppDelegate следующий код:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {

        return UIInterfaceOrientationMaskAllButUpsideDown;

    } else {

        return UIInterfaceOrientationMaskAll;

    }

}

Ответ 8

Для меня у меня была такая же проблема, как у jaredsinclair, но подклассификация UIViewController с помощью метода supportedInterfaceOrientations не решала проблему. Вместо этого я сделал именно то, что он сделал в моем методе appDidFinishLaunching моего AppDelegate, и добавил мой UITabBarController в качестве ребенка к нормальному UIViewController, а не к его подклассу, и он сработает!

Ответ 9

Я в той же ситуации, и [self.window setFrame:...] не работает для меня.

Добавление следующего в конце приложения: didFinishLaunchingWithOptions - единственное, что я нашел, что работает. Это делает экран мигающим и не совсем чистым и эффективным.

Я добавил это в конце приложения: didFinishLaunchingWithOptions:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navController presentViewController:nc animated:NO completion:nil];
[self.navController dismissViewControllerAnimated:NO completion:nil];  
[UIViewController attemptRotationToDeviceOrientation];

Ответ 10

У меня была аналогичная проблема с тем, что мое приложение работает как в ландшафтном, так и в портретном режиме с помощью UITabBarController в качестве контроллера корневого представления.

Всякий раз, когда приложение запускалось в ландшафтном режиме, представление было неправильным.

Все, что мне нужно было сделать: - удалить назначение контроллера rootview в XIB. - Вручную добавьте его после запуска приложения:


  • (void) applicationDidFinishLaunching: (приложение UIApplication *) { application.statusBarHidden = YES;

    [self.window setRootViewController: self.tabBarController];


Это устранило проблему.

Ответ 11

Просто удалите все элементы в поддерживаемой ориентации интерфейса, кроме того, что вы хотите (мне нужен только портрет) в info.plist, он будет работать для меня введите описание изображения здесь

Ответ 12

просто позвоните [application setStatusBarOrientation: UIInterfaceOrientationPortrait анимированный: NO]; в методе делегата приложения - (BOOL) приложение: (UIApplication *) приложение didFinishLaunchingWithOptions: (NSDictionary *) launchOptions

на самом деле теперь устройство UIInterfaceOrientationPortrait после запуска, если вы касаетесь входного поля, клавиатура представляет собой макет портрета