IOS 5: willRotateToInterfaceOrientation: продолжительность не вызывается, когда первый контроллер загрузки

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

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

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

В iOS 4 он также вызывается, когда контроллер сначала загружается (независимо от того, изменяется ли ориентация или нет, он получает один раз в начале с правильной ориентацией).

Проблема в том, что я заметил, что в iOS 5 этого больше не происходит. Метод вызывается при изменении ориентации, но не при загрузке контроллера. Это проблема для меня, потому что я полагаюсь на это, чтобы настроить размещение исходного представления на основе ориентации.

Любые идеи, почему это поведение изменилось? Какой лучший способ справиться с этим? Должен ли я проверить, что такое ориентация в viewDidLoad, если на iOS 5, а затем вручную вызвать методы willRotate и didRotate? Это немного похоже на взлом.

Спасибо за любой ввод, который вы можете предоставить.

Ответ 1

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

В viewDidLoad я добавил следующее:

if ( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0") ) {
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self willRotateToInterfaceOrientation:interfaceOrientation duration:0.2f];
}

Затем я добавил это в общий заголовочный файл:

// iOS Version Checking
#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

Я установил проверку версии iOS из ответа на этот вопрос в SO.

Ответ 2

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

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [_tabBarConroller willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

Надеюсь, это поможет!

Ответ 3

Я столкнулся с этой проблемой и вытащил свои волосы. Я наконец нашел решение, но, к сожалению, это будет только iOS 5.0 +:

Поместите следующий код в свой метод viewDidLoad в свой пользовательский UIViewController:

double delayInSeconds = 0.1f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [UIViewController attemptRotationToDeviceOrientation];
});

Это приведет к обновлению вращения для следующего цикла цикла. attemptRotationToDeviceOrientation - это iOS 5.0+.

Ответ 4

Поскольку iOS 5 и выше вы должны создать иерархию контроллеров представлений (используя -addChildViewController:). Затем контроллеры детского представления снова вызовут -willRotateToInterfaceOrientation: interfaceOrientation: и другие связанные с интерфейсом методы (поскольку родительский контроллер уведомляет их об изменениях ориентации пользовательского интерфейса).

Пожалуйста, не используйте "грязные" методы.

Полезная документация: Apple docs о 'addChildViewController:'