Вращение iPhone и создание нового UIViewController? - PullRequest
7 голосов
/ 08 апреля 2009

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

Я попытался создать новый контроллер в методах willRotateToInterfaceOrientation и didRotateFromInterfaceOrientation, но ни один из этих методов не вызывается !. Я подозреваю, что это потому, что текущий контроллер вставляется контроллером навигации, который сам обрабатывается tabBarController. Любая подсказка? Очень приветствуется простой фрагмент кода.

Заранее спасибо.

Ответы [ 4 ]

29 голосов
/ 21 мая 2009

Более чистым способом НЕ является использование UIInterfaceOrientation для вращения.

Почему, потому что тогда ваш интерфейс или представление 1 действительно вращается. Это означает, что вы должны повернуть его обратно, чтобы снова отобразить его после удаления представления 2.

Чтобы компенсировать это, я просто подписываюсь на UIDeviceOrientation уведомлений. Сильно отличается. Представление 1 не должно поддерживать авторотацию, чтобы этот метод работал. В viewDidLoad введите следующий код:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectOrientation) name:@"UIDeviceOrientationDidChangeNotification" object:nil];

Тогда просто определите метод detectOrientation:

-(void) detectOrientation {

     if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
            ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) {

        //load view 2


    } else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) {

        // load view 1

    }   
}

Теперь ни один из ваших взглядов не нуждается в поддержке автоповорота! Однако перед загрузкой вам необходимо выполнить преобразование в представлении 2:

-(void) transformView2ToLandscape {

  NSInteger rotationDirection;
  UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];

  if(currentOrientation == UIDeviceOrientationLandscapeLeft){
    rotationDirection = 1;
  }else {
    rotationDirection = -1;
  }

  CGRect myFrame = CGRectMake(0, 0, 480, 300);
  CGAffineTransform transform = [[self view2] transform];
  transform = CGAffineTransformRotate(transform, degreesToRadians(rotationDirection * 90));
  [[self view2] setFrame: myFrame];
  CGPoint center = CGPointMake(myFrame.size.height/2.0, myFrame.size.width/2.0);
  [[self view2] setTransform: transform];
  [[self view2] setCenter: center];

}

Это то, как я меняю виды на вращение без поддержки автоповорота в моих видах.

7 голосов
/ 08 апреля 2009

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

Так что вам нужно заставить их разрешить все изменения ориентации через: - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation { вернуть ДА; }

Затем, чтобы загрузить новый контроллер представления, вы должны ответить:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) ||
     (fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
  {    
    // Load the view controller you want to display in landscape mode...
  }
}

и может также использовать:

-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

Чтобы определить, что произойдет изменение ориентации.

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

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

Надеюсь, это немного поможет.

Пол

3 голосов
/ 03 июля 2009

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

Добавьте это к контроллеру панели вкладок:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [self.selectedViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
1 голос
/ 08 апреля 2009

Реализуете ли вы долженAutorotateToInterfaceOrientation? Если нет, возможно, именно поэтому вы не получаете сообщения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...