UINavigationController Force Rotate

Мое приложение - в основном портрет, однако есть одно представление, которое ТРЕБУЕТ ландшафтной ориентации.

Мои представления содержатся в UINavigationController, который (по-видимому) является причиной этой проблемы.

Все UIViewControllers, кроме одного, имеют следующее:

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

UIViewController, который требует Landscape, имеет следующее:

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

Теперь, когда пользователь достигает ландшафта UIViewController, он отображается в портрете. Затем пользователь может поворачивать свой телефон, и он отображается в ландшафте, так как я хочу его (блокировка для пейзажа). Затем пользователь переходит к портрету UIViewController, и это происходит: он начинается с пейзажа, затем они поворачивают свой телефон и снова становятся портретами (и блокируются для портрета).

Кажется, блокировка ориентации запрещена между UIViewControllers, однако автоматическое вращение/программное изменение ориентации каким-то образом заблокировано.

Как заставить телефон обновляться до правильной ориентации?

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

Ответ 1

У меня было одно и то же требование для одного из моих приложений!!!

К счастью, я нашел решение!

Чтобы сохранить основной ландшафт viewcontroller, независимо от того, какую ориентацию он выскочил/нажал, я сделал следующее: (in viewWillAppear:)

//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];

//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];

P.S.Tested на sdk 3.2.5 ios 5.0.1.

P.S. В предыдущем ответе iOS 8 некоторые мерцания экрана, а также - он нестабилен (в некоторых случаях он больше не работает для меня.) Итак, для моих нужд я изменил код на: (ARC)

//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];

[self.navigationController presentViewController:[UIViewController new] animated:NO completion:^{
    dispatch_after(0, dispatch_get_main_queue(), ^{
        [self.navigationController dismissViewControllerAnimated:NO completion:nil];
    });
}];

//I added this code in viewDidDissapear on viewController class, which will be popped back.

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

Ответ 2

Это может помочь. При необходимости вы можете вызвать следующий метод. например в -viewWillAppear:animated

attemptRotationToDeviceOrientation Попытка повернуть все окна к ориентации устройства.

+ (void)attemptRotationToDeviceOrientation

Обсуждение

Некоторые диспетчеры представлений могут захотеть использовать условия приложения для определить возвращаемую стоимость их реализации shouldAutorotateToInterfaceOrientation: метод. Если ваш взгляд контроллер делает это, когда эти условия меняются, ваше приложение должно вызовите этот метод класса. Система немедленно пытается повернуть новой ориентации. Вращение происходит до тех пор, пока каждое соответствующее представление контроллер возвращает YES в своей реализации shouldAutorotateToInterfaceOrientation: метод.

Наличие

Доступно в iOS 5.0 и более поздних версиях. http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html

Ответ 3

Используйте это,

[[UIDevice currentDevice]performSelector:@selector(setOrientation:) withObject:(__bridge id)((void *)UIInterfaceOrientationLandscapeRight)];