2015-05-07 8 views
3

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

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

Warning: Attempt to present on whose view is not in the window hierarchy!`.

Что можно лучше подождать, пока анимация не будет а затем изменить поворот?

Это то, что я использую на Представление вида контроллера:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self beginDeviceOrientationListener]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)beginDeviceOrientationListener 
{ 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]]; 
} 

- (void)orientationChanged:(NSNotification *)notification 
{ 
    UIDevice *device = notification.object; 
    switch (device.orientation) 
    { 
     case UIDeviceOrientationLandscapeLeft: 
     case UIDeviceOrientationLandscapeRight: 
     { 
      TheViewControllerToPresent *viewController = [[TheViewControllerToPresent alloc] init]; 
      [self presentViewController:viewController animated:YES completion:nil]; 
      [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"]; 
      [[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES]; 
      [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; 
     } 
      break; 

     default: 
      break; 
    } 
} 

Это то, что я использую на Представлено контроллер представления:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self beginDeviceOrientationListener]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)beginDeviceOrientationListener 
{ 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]]; 
} 

- (void)orientationChanged:(NSNotification *)notification 
{ 
    UIDevice *device = notification.object; 
    switch (device.orientation) 
    { 
     case UIDeviceOrientationPortrait: 
     { 
      [self dismissViewControllerAnimated:YES completion:nil]; 
      [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"]; 
      [[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES]; 
     } 
      break; 
     default: 
      break; 
    } 
} 
+0

Почему вы устанавливаете '[UIDevice orientation]'? какой ужасный взлом это? – Sulthan

+0

Ну, на самом деле это работает очень хорошо, почему взломать? что я должен использовать вместо этого? –

+0

'[UIDevice orientation]' is readonly по причине. Взлом заключается в том, что вы обращаетесь к нему с помощью отражения ('setValue:'), обходя статус 'readonly'. Если вы не хотите использовать поддержку вращения по умолчанию, которую имеют контроллеры, вы можете просто использовать 'transform' в представлении представленного контроллера. – Sulthan

ответ

2

Наиболее Простейшее решение, которое я использую самостоятельно, - это запрет пользователю вносить какие-либо изменения во время анимации.

Это делается путем добавления следующего кода при запуске анимации:

[[UIApplication sharedApplication] beginIgnoringInteractionEvents]; 
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 

и обработчик завершения:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
[[UIApplication sharedApplication] endIgnoringInteractionEvents]; 

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

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 

, чтобы узнать, следует ли начинать новую анимацию или нет.

 Смежные вопросы

  • Нет связанных вопросов^_^