setStatusBarOrientation проблема

У меня есть приложение для контроллера навигации. И сначала я нажимаю FirstViewController (поддерживает портретную ориентацию), а затем SecondViewController (поддерживает все ориентации). Когда я нахожусь в ландшафтном режиме SecondViewController и нажимаю кнопку «Назад», FirstViewController появляется в ландшафтном режиме. Вот почему я вручную поворачиваю представление навигации, но когда я хочу установить для setStatusBarOrientation значение «Портрет» (контроллер первого представления должен отображаться только в портретном режиме), ориентация контроллера представления по-прежнему будет альбомной, и даже если повернуть устройство в портретный режим, ориентация остается ландшафтной. Вот мой код FirstViewController:

- (void)viewWillAppear:(BOOL)animated
{
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            prevInterfaceOrientation = UIInterfaceOrientationLandscapeLeft;
            self.navigationController.view.transform = CGAffineTransformIdentity;
            self.navigationController.view.transform =
            CGAffineTransformMakeRotation(degreesToRadians(90));
        }
        else if (self.interfaceOrientation ==
                 UIInterfaceOrientationLandscapeRight) {
            prevInterfaceOrientation = UIInterfaceOrientationLandscapeRight;
            self.navigationController.view.transform = CGAffineTransformIdentity;
            self.navigationController.view.transform =
            CGAffineTransformMakeRotation(degreesToRadians(-90));
        }
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
        [self.tableViewDetail reloadData];
    }


}

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
     return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{ 
    if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
    {
        if (prevInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            self.navigationController.view.transform = CGAffineTransformIdentity;
        }
        else if (prevInterfaceOrientation ==
                 UIInterfaceOrientationLandscapeRight) {
            self.navigationController.view.transform = CGAffineTransformIdentity;
        }
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
        [self.tableViewDetail reloadData];
    }
}

Я даже пробовал использовать:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    if (UIInterfaceOrientationIsLandscape(prevInterfaceOrientation))
    {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    }
}

но self.interfaceOrientation по-прежнему остается альбомной при повороте в портретную ориентацию. Но мне действительно нужно вручную повернуть представление в портретный режим, чтобы пользователи могли видеть, что FirstViewController поддерживает только портретную ориентацию. У меня есть возможность разместить представление SecondViewController в MainWindow (например, в модальном окне), но мне не нравится эта идея, потому что, если у Apple есть метод setStatusBarOrientation, мне кажется, что это должно быть правильное решение этой проблемы.


person Paul T.    schedule 29.05.2012    source источник


Ответы (3)


Я бы избавился от преобразований и использовал

      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:animated];

Это в сочетании с принудительной перерисовкой стека представлений сделает это. Это можно сделать, добавив следующее в viewDidAppear к первому контроллеру (это не работает в viewWillApear).

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

       UIWindow *window = [[UIApplication sharedApplication] keyWindow];
       if ([window.subviews count] > 0) {
           UIView *view = [window.subviews objectAtIndex:0];
           [view removeFromSuperview];
           [window insertSubview:view atIndex:0];
       }
       else {
           DLog(@"NO view to force rotate?");
       }

К сожалению, анимация перехода не очень четкая, когда вы это делаете, поэтому я бы рекомендовал сделать снимок портретного экрана, наложить его на свой вид, а затем затухать с помощью отдельной анимации.

person Steven Veltema    schedule 15.06.2012

Ответ Стивена Велтема не сработал для меня.

У меня был один контроллер вида, где разрешены все ориентации, а остальные поддерживали только портретную ориентацию. Когда у меня был первый контроллер представления в альбомной ориентации и я перешел к другому контроллеру представления, ориентация не обновлялась, как вы это делаете.

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

- (void)viewDidAppear:(BOOL)animated
{
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        UIViewController * viewController = [[UIViewController alloc] init];
        [self presentModalViewController:viewController animated:NO];
        [viewController dismissModalViewControllerAnimated:NO];
    }

    [super viewDidAppear:animated];
    ....
}
person Morten Holmgaard    schedule 28.03.2013

Еще одно быстрое решение:

  1. Щелкните свой проект на левой боковой панели.
  2. В общих настройках выберите вариант «Скрывать при запуске приложения».
person starea    schedule 20.05.2014