Просмотр уведомлений о повороте: почему didRotateFromInterfaceOrientation: не вызывается?

#iphone #ios #uiviewcontroller #uiinterfaceorientation

#iPhone #iOS #uiviewcontroller #uiinterfaceorientation

Вопрос:

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

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

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
  

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

  willRotateToInterfaceOrientation:duration:
 willAnimateRotationToInterfaceOrientation:duration:
 didRotateFromInterfaceOrientation:
 willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
 didAnimateFirstHalfOfRotationToInterfaceOrientation:
 willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
  

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

Я также попробовал этот фрагмент кода:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  

Но по-прежнему ничего. Итак, мне интересно, запускает ли симулятор уведомления о вращении?
Если да, то что я делаю не так?

Комментарии:

1. где вы внедрили этот метод?

2. Да, симулятор отправляет уведомление о ротации.

3. @Ishu: спасибо за информацию; @Deepak: если вы имеете в виду метод didRotateFromInterfaceOrientation, я реализовал его в файле .m моего контроллера представления; если вы говорите о [[UIDevice currentDevice], инициирующем настройку deviceorientationnotifications], я сделал это в viewDidLoad контроллера представления

Ответ №1:

Вам нужно добавить notification observer что-то вроде

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
  

и добавьте метод

 - (void) didRotate:(NSNotification *)notification
{   
      UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

       if (orientation == UIDeviceOrientationLandscapeLeft)
      {
        NSLog(@"Landscape Left!");
      }
}
  

Комментарии:

1. Спасибо, это как раз то, что мне было нужно — похоже, существует общая рекомендация, что [UIApplication sharedApplication].statusBarOrientation является более надежным [чем ориентация пользовательского устройства], поэтому люди могут захотеть использовать первое — я, безусловно.

2. Обратите внимание, что в приведенном выше коде UIDeviceOrientationDidChangeNotification должно быть константой, а не фактическим значением. Просто так получилось, что значением константы является UIDeviceOrientationDidChangeNotification 🙂

3. с учетом зависимости ориентации statusBarOrientation от текущей ориентации устройства, некоторые быстрые тесты с моей стороны показывают, что проверка statusBarOrientation в этом варианте использования фактически возвращает предыдущую ориентацию, в то время как currentDevice возвращает текущую / новую ориентацию. Кроме того, currentDevice будет включать UIDeviceOrientationFaceUp и UIDeviceOrientationFaceDown, в то время как строка состояния никогда этого не делает.

Ответ №2:

Краткое изложение, измените это:

 [window addSubview:viewController.view];
  

к этому:

 [window setRootViewController:viewController];
  

Прошу прощения, если я отнял у кого-то время из-за своей глупой ошибки. Я выяснил, почему метод – willRotateToInterfaceOrientation:duration: никогда не вызывался. Что-то привлекло мое внимание к контроллеру навигации:

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

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

 CGRect bound = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, bound.size.width, bound.size.height)];
TestViewController *viewController = [[TestViewController alloc] init];
[window addSubview:viewController.view];
[viewController release];
[self.window makeKeyAndVisible];
  

Проблема заключалась в том, что я не устанавливал какой-либо контроллер просмотра для окна, а просто добавлял представление. Это была ошибка, которую я допустил из-за спешки, чтобы что-то протестировать. Мне пришлось исправить код следующим образом:

 CGRect bound = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, bound.size.width, bound.size.height)];
TestViewController *viewController = [[TestViewController alloc] init];
[window setRootViewController:viewController];
[viewController release];
[self.window makeKeyAndVisible];