Как заставить UIViewController к портретной ориентации в iOS 6
Как ShouldAutorotateToInterfaceOrientation устарел в iOS 6, и я использовал это, чтобы заставить определенный вид портрет только, что правильный способ сделать это в iOS 6? Это только для одной области моего приложения, все остальные виды могут вращаться.
16 ответов:
Если вы хотите, чтобы все наши навигационные контроллеры уважали контроллер верхнего вида, вы можете использовать категорию, поэтому вам не нужно проходить и изменять кучу имен классов.
@implementation UINavigationController (Rotation_IOS6) -(BOOL)shouldAutorotate { return [[self.viewControllers lastObject] shouldAutorotate]; } -(NSUInteger)supportedInterfaceOrientations { return [[self.viewControllers lastObject] supportedInterfaceOrientations]; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation]; } @endКак показывают некоторые комментарии, это быстрое решение проблемы. Лучшим решением является подкласс UINavigationController и поместить эти методы там. Подкласс также помогает для поддержки 6 и 7.
лучший способ для iOS6 специально отмечается в "iOS6 by Tutorials" командой Ray Wenderlich -http://www.raywenderlich.com/ и это лучше, чем подклассы
UINavigationControllerв большинстве случаев.я использую iOS6 с раскадровкой, которая включает в себя
UINavigationControllerустановить в качестве начального контроллера вида./ / AppDelegate.m - этот метод не доступен pre-iOS6 к сожалению
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown; if(self.window.rootViewController){ UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject]; orientations = [presentedViewController supportedInterfaceOrientations]; } return orientations; }//MyViewController.м - возврата независимо от направления вы хотите поддержка для каждого
UIViewController- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
этот ответ относится к вопросам, заданным в комментариях к сообщению ОП:
чтобы заставить представление появиться в заданной ориентации, поместите следующее в viewWillAppear:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [self presentModalViewController:c animated:NO]; [self dismissModalViewControllerAnimated:NO]; }это немного хак, но это заставляет
UIViewControllerдолжен быть представлен в портрете даже если предыдущий контроллер был пейзажобновление для iOS7
приведенные выше методы теперь устарели, поэтому для iOS 7 Используйте следующее:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [c.view setBackgroundColor:[UIColor redColor]]; [self.navigationController presentViewController:c animated:NO completion:^{ [self.navigationController dismissViewControllerAnimated:YES completion:^{ }]; }]; }интересно, что на момент написания статьи,или настоящее или отклонить должны быть анимированы. Если нет, то вы получите белый экран. Не знаю, почему это заставляет его работать, но это так! Визуальный эффект отличается в зависимости от того, какой анимированный.
так что я столкнулся с той же проблемой при отображении портрета только модальные виды. Обычно, я бы создал
UINavigationController, выберитеviewControllerкакrootViewController, то вывестиUINavigationControllerкак модальное представление. Но с iOS 6, тоviewControllerтеперь попросит navigationController для его поддерживаемых ориентаций интерфейса (который, по умолчанию, теперь все для iPad и все, кроме перевернутого для iPhone).решение: Я должен был подкласс
UINavigationControllerи переопределить методы авторотации. Как-то неубедительно.- (BOOL)shouldAutorotate { return NO; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } // pre-iOS 6 support - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (toInterfaceOrientation == UIInterfaceOrientationPortrait); }
IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return (interfaceOrientation == UIInterfaceOrientationPortrait); }IOS 6
-(BOOL)shouldAutorotate{ return YES; } -(NSInteger)supportedInterfaceOrientations{ // UIInterfaceOrientationMaskLandscape; // 24 // // UIInterfaceOrientationMaskLandscapeLeft; // 16 // // UIInterfaceOrientationMaskLandscapeRight; // 8 // // UIInterfaceOrientationMaskPortrait; // 2 // return UIInterfaceOrientationMaskPortrait; // or return 2; }
Я не согласен с ответом @aprato, потому что методы вращения UIViewController объявляются в самих категориях, что приводит к неопределенному поведению при переопределении в другой категории. Его безопаснее переопределить их в подклассе UINavigationController (или UITabBarController)
кроме того, это не распространяется на сценарий, в котором вы нажимаете / present / pop из ландшафтного вида в портрет только VC или наоборот. Чтобы решить эту сложную проблему (никогда не обращался к Apple), вы должны:
в iOS = 6:
UIViewController *vc = [[UIViewController alloc]init]; [self presentModalViewController:vc animated:NO]; [self dismissModalViewControllerAnimated:NO]; [vc release];в iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];Это действительно форс-программирования с использованием UIKit, чтобы заново оценить все ваши shouldAutorotate , supportedInterfaceOrientations и т. д.
у меня очень хороший подход смешивания https://stackoverflow.com/a/13982508/2516436 и https://stackoverflow.com/a/17578272/2516436
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown; if(self.window.rootViewController){ UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController]; orientations = [presentedViewController supportedInterfaceOrientations]; } return orientations; } - (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController { if ([rootViewController isKindOfClass:[UITabBarController class]]) { UITabBarController* tabBarController = (UITabBarController*)rootViewController; return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { UINavigationController* navigationController = (UINavigationController*)rootViewController; return [self topViewControllerWithRootViewController:navigationController.visibleViewController]; } else if (rootViewController.presentedViewController) { UIViewController* presentedViewController = rootViewController.presentedViewController; return [self topViewControllerWithRootViewController:presentedViewController]; } else { return rootViewController; } }и возвращайте любые ориентации, которые вы хотите поддерживать для каждого UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
у меня есть относительно сложное Универсальное приложение, использующее UISplitViewController и UISegmentedController, и есть несколько представлений, которые должны быть представлены в ландшафте с помощью
presentViewController. Используя методы, предложенные выше, я смог заставить iPhone ios 5 & 6 работать приемлемо, но по какой-то причине iPad просто отказался представить как пейзаж. Наконец, я нашел простое решение (реализованное после нескольких часов чтения и проб и ошибок), которое работает как для устройств, так и для ios 5 и 6.Шаг 1) На контроллере укажите необходимую ориентацию (более или менее, как указано выше)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { NSInteger mask = UIInterfaceOrientationMaskLandscape; return mask; }Шаг 2) создайте простой подкласс UINavigationController и реализуйте следующие методы
-(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }Шаг 3) Представьте ваш viewController
vc = [[MyViewController alloc]init]; MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc]; [self myNavigationController animated:YES completion:nil];надеюсь, что это полезно для кого-то.
не быть скучным здесь, но не будете ли вы так любезны поделиться своим подклассом? Спасибо.
edit: ну, я, наконец, сделал это, подкласс был мертв просто сделать. Я просто должен был объявить
navigationControllerнаAppDelegateкакUINavigationControllerSubclassвместоUINavigationController, затем изменил свой подкласс с помощью:- (BOOL)shouldAutorotate { return _shouldRotate; }поэтому я могу установить любой вид, который я хочу повернуть или нет, позвонив по адресу
viewDidLoad_navController = (UINavigationController *)self.navigationController; [_navController setShouldRotate : YES / NO]надеюсь, что эта настройка поможет и другим, Спасибо за ваш чаевые!
совет: используйте
- (NSUInteger)supportedInterfaceOrientationsв контроллерах вида, так что вы не в конечном итоге, имея портрет желаемого вида в ландшафте или наоборот.
Я не проверял его сам, но в документации говорится, что теперь вы можете переопределить эти методы:
supportedInterfaceOrientationsиpreferredInterfaceOrientationForPresentation.вы, вероятно, можете достичь того, что вы хотите y установка только ориентацию, которую вы хотите в этих методах.
ответы, использующие подклассы или категории, чтобы разрешить VCs в классах UINavigationController и UITabBarController, работают хорошо. Не удалось запустить модальный режим только для портрета из контроллера панели вкладок ландшафта. Если вам нужно это сделать, то используйте трюк отображения и скрытия не анимированного модального представления, но сделайте это в методе viewDidAppear. Это не сработало для меня в viewDidLoad или viewWillAppear.
кроме того, решения выше работают нормально.
для Monotouch вы можете сделать это следующим образом:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { return UIInterfaceOrientationMask.LandscapeRight; } public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation() { return UIInterfaceOrientation.LandscapeRight; }
Я вижу много ответов, но не получаю конкретной идеи и ответа об ориентации, но вижу, что ссылка хорошо понимает ориентацию и удаляет принудительное вращение для ios6.
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
Я думаю, что это поможет.
просто перейдите в проект.файл plist затем добавить поддерживаемые ориентации интерфейса, а затем добавить только портрет (нижняя кнопка Home) и портрет (верхняя кнопка Home).
вы можете добавить или удалить там ориентацию в соответствии с вашим требованием проекта .
спасибо
1) Проверьте настройки проекта и информацию.plist и убедитесь, что выбраны только те ориентации, которые вы хотите.
2) добавьте следующие методы в самый верхний контроллер вида (контроллер навигации/контроллер табуляции)
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }3) добавьте следующие методы в делегат приложения
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskPortrait; }
положите это в поле .m файл каждого
ViewControllerвы не хотите повернуть:- (NSUInteger)supportedInterfaceOrientations { //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; return UIInterfaceOrientationMaskPortrait; }посмотреть здесь для получения дополнительной информации.
Comments