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:'