2014-10-22 3 views
8

Я нашел небольшое изменение поведения между 7.1 и 8 по методу UIViewController shouldAutorotate. В Apple View Controller Programming Guide указано, что Этот метод вызывается перед выполнением любой авторотации.shouldAutorotate поведение в iOS 8

Однако я заметил, что когда я просто отключил shouldAutorotate (return NO), метод вызывается в режиме Portrait -> Landscape, но не в следующем Landscape -> Portrait rotation. Опять же метод всегда следует называть, как я его понимаю. Это происходит при работе на iOS 8, но не на iOS 7.1.

Это кажется связано с новым методом в стеке вызовов в iOS8:

[UIWindow shouldAutorotateToInterfaceOrientation:checkForDismissal:isRotationDisabled]

Я не мог найти Есть ли описание этого метода и его поведение, любая идея, где я мог бы найти больше информация об этом внутреннем методе?

Простые шаги, чтобы воспроизвести это:

  1. Создать новую Single View Application проект в Xcode
  2. Обновите свою ViewController.m реализовать shouldAutorotate

    - (BOOL)shouldAutorotate 
    { 
        UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
        NSLog(@"%s orientation is %@", __PRETTY_FUNCTION__, [self stringFromDeviceOrientation:orientation]); 
        // Disable autorotation of the interface. 
        return NO; 
    } 
    
    - (NSString *) stringFromDeviceOrientation:(UIDeviceOrientation)uido 
    { 
        NSString *orientation = @"UIDeviceOrientationUnknown"; 
        switch (uido) { 
         case UIDeviceOrientationPortrait: 
          orientation = @"Portrait"; 
          break; 
         case UIDeviceOrientationPortraitUpsideDown: 
          orientation = @"PortraitUpsideDown"; 
          break; 
         case UIDeviceOrientationLandscapeRight: 
          orientation = @"LandscapeRight"; 
          break; 
         case UIDeviceOrientationLandscapeLeft: 
          orientation = @"LandscapeLeft"; 
          break; 
         case UIDeviceOrientationFaceDown: 
          orientation = @"FaceDown"; 
          break; 
         case UIDeviceOrientationFaceUp: 
          orientation = @"FaceUp"; 
          break; 
          default: 
           break; 
         } 
         return orientation; 
        } 
    
  3. Запуск на тренажере iPhone 5s (7.1): shouldAutorotate вызывается при переключении на пейзаж и обратно в портрет

  4. Запуск на симулятор iPhone 5s (8.0) или iPhone 6: shouldAutorotate вызывается при переключении на Пейзаж, но он не называется при переключении обратно в портрет.

ответ

9

То же самое происходило со мной. У меня такое чувство, что в iOS8 есть ошибка, потому что мой же код отлично работал в iOS7. Также как пользователь, у меня было много проблем с поворотом в приложениях, которые я использую. В 8 shouldAutorotate звонит, когда вы вращаетесь в сторону, но не снова, когда возвращаетесь к нормальному вращению. То есть, если он фактически не сделал авторотацию в сторону, и в этом случае по возвращению он называется.

Итак, это потому, что ваш `shouldAutorotate 'всегда возвращает« НЕТ ». Мое предположение заключается в том, что по какой-то причине в iOS8 они (яблочные кодеры, которые изменили это поведение) решили, что если они будут иметь НЕТ при повороте в сторону, им не нужно вызывать shouldAutorotate при повороте назад к портрету. Таким образом, это нарушило поведение, которого мы ожидали.

Никто не говорит об этом и не жалуется. Google не дает почти никаких результатов для этого точного сценария. Я думаю, это потому, что для того, чтобы это произошло, вы должны пытаться использовать «shouldAutorotate» в качестве уведомления о ротации устройства, но НЕ использовать функции автоматического поворота ОС. Например, я делаю opengl игры. Поэтому я просто хочу, чтобы мой движок знал, чтобы повернуть графику игры. Но я не поворачиваю свое мнение. Я не думаю, что многие люди использовали это для уведомлений о ротации устройства.

Поэтому я решил использовать уведомления устройств.В моем контроллере представления:

- (void) movingToBackground: (NSNotification *) notification { 
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 
} 

- (void) movingToForeground: (NSNotification *) notification { 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
} 

И получать сообщения:

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

и метод:

- (void)viewChanging:(NSNotification*)notification 
{ 
    NSLog(@"View is changing"); 
    previousOrientation = orientation; 
    orientation = [[UIDevice currentDevice] orientation]; 

    if (previousOrientation==orientation && forceReorientation==NO) { 
     return; 
    } 
    ... do stuff ... 

, а затем обратно на мой взгляд контроллера я повернул все авто вращения вещи в NO.

+1

Я согласен с вашим анализом, метод на обратном пути не вызван, вероятно, из-за этого нового 'shouldAutorotateToInterfaceOrientation' и его' isRotationDisabled'. Ваше обходное решение (с использованием уведомлений) является правильным способом, и нет гарантии, что будет вызываться код авторотации, особенно сейчас, когда iOs 8 обрабатывает вращения с изменением размера. Я подожду немного, прежде чем принять ваш ответ, если появится больше информации. – lazi74

+1

спасибо. Кстати, я использую вышеуказанный код сейчас в своих приложениях и, похоже, работает. Мое единственное беспокойство заключалось в том, что beginGeneratingDeviceOrientationNotifications может вызвать слишком много уведомлений при каждом небольшом повороте, даже если это не полный 90 градусов. Но я не вижу изменения «Просмотр меняется», кроме фактических поворотов устройства. Поэтому я думаю, что это хорошо. – badweasel

+0

У вас есть решение? Я делаю замечательное управление поворотом строки состояния. И все же удалось получить скоординированную акселерометром навигацию по протоколу URL из другого приложения или вернуться из другой ориентации. Но, к сожалению, остановился на шаге, где экранная клавиатура должна вращаться соответственно. В моем решении у меня есть (как и вы) фиксированный портретный вид с его слоем OpenGL. Как заставить iOS НЕ анимировать его ужасное вращение ??? :-) –

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