willAnimateRotationToInterfaceOrientation не вызывается для popViewControllerAnimated - PullRequest
11 голосов
/ 29 августа 2010

В MainViewController мне нужно настроить некоторые изображения на изменение ориентации. Легко - просто добавьте код в willAnimateRotationToInterfaceOrientation: обратный вызов

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {
  NSLog(@"orientation: %@", name(orientation));
  ..

Работает как положено. Находясь в режиме «Портрет», я помещаю другой UIViewController, ориентированный на ориентацию, в UINavigationController. Я поворачиваюсь в Пейзаж, и все хорошо.

Затем я возвращаюсь к MainViewController, вызывая

[self.navigationController popViewControllerAnimated:YES];

В то время как подпредставления MainViewController настроены на альбомную ориентацию в соответствии с масками авторазмера, willAnimateRotationToInterfaceOrientation: не вызывается!

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

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

Чего мне не хватает?

Ответы [ 5 ]

36 голосов
/ 30 августа 2010

Это ожидаемое поведение, как я его вижу.Если UIVC не находится на вершине стека, то не следует вызывать willAnimateRotationToInterfaceOrientation, поскольку в это время вращение не анимируется.То, как я справляюсь с этим в приложении, над которым я сейчас работаю, похоже на приведенный выше плакат.Любой UIVC, который поддерживает все ориентации, получает новый метод

- (void) updateLayoutForNewOrientation: (UIInterfaceOrientation) orientation;

Этот метод вызывается из двух мест:

<code>
-(void) viewWillAppear: (BOOL) animated {
  [super viewWillAppear: animated];
  [self updateLayoutForNewOrientation: self.interfaceOrientation];
}</p>

<p>-(void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration {
  [self updateLayoutForNewOrientation: interfaceOrientation];
}

Новый метод прост:

<code>
- (void) updateLayoutForNewOrientation: (UIInterfaceOrientation) orientation {
    if (UIInterfaceOrientationIsLandscape(orientation)) {
        // Do some stuff
    } else {
        // Do some other stuff
    }
}

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

2 голосов
/ 29 августа 2010

Разве это не правильное поведение? Поскольку обратный вызов анимации должен вызываться только до изменения анимированной ориентации. Когда вы открываете самый верхний вид, вы видите всплывающую анимацию, а затем уже повернутый вид внизу. Там нет анимации вращения и, следовательно, нет обратного вызова. (Но вы обязательно должны получить willRotateToInterfaceOrientation:duration:.)

P.S. У меня есть пример проекта Xcode для экспериментов по ориентации интерфейса на GitHub, вам может быть интересно.

1 голос
/ 30 августа 2010

Я со Скоттом в этом вопросе - я думаю, что такое поведение следует ожидать.

См. Также Руководство по программированию контроллера представления , где говорится, что только передний контроллербудет вызывать методы.(Найдите «самый передний», чтобы найти два соответствующих местоположения в документе.)

1 голос
/ 29 августа 2010

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

- (void)viewWillAppear:(BOOL)animated {
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsPortrait(statusBarOrientation)){
        NSLog(@"Portrait");
....your code....
    }
    else {
        NSLog(@"Landscape");
....your code....
    }


}
0 голосов
/ 29 августа 2010

Я также испытал это поведение, и я думаю, что это из-за производительности и архитектурных соображений; AFAIK этот метод вызывается внутри контекста анимации UIView (который позволяет вам изменять кадры и центры, и иметь хорошую анимацию, когда все вращается), и когда ваш контроллер представления не виден, либо UIKit избегает выполнения этого метода, либо просто невозможно выполнить его, потому что представление не видно (и, вероятно, вы не можете анимировать то, что видите). Опять же, это чистое предположение:)

...