如何强制iOS 6中的UIViewController纵向

由于ShouldAutorotateToInterfaceOrientation在iOS 6中已被弃用,我使用它来强制一个特定的视图只有肖像 ,在iOS 6中做到这一点的正确方法是什么? 这只是我的应用程序的一个区域,所有其他视图可以旋转。

如果您希望我们所有的导航控制器都遵守顶视图控制器,您可以使用一个类别,因此您不必经过并更改一堆类名称。

 @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 

正如一些评论指出的那样,这是对问题的快速解决。 更好的解决scheme是UINavigationController的子类,并把这些方法放在那里。 一个子类也有助于支持6和7。

对于iOS6来说,最好的方法是在Ray Wenderlich团队的“iOS6 By Tutorials”( http://www.raywenderlich.com/)中注明,并且比大多数情况下的;UINavigationController的子类更好。

我正在使用包含一个UINavigationController设置为初始视图控制器的故事板的iOS6。

//AppDelegate.m – 这个方法在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.m – 返回每个UIViewController支持的方向

 - (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } 

这个答案与OP的文章评论中提出的问题有关:

要强制视图出现在给定的方向,请将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:^{ }]; }]; } 

有趣的是,在撰写本文时, 无论是现在还是解雇都必须是animation的。 如果两者都不是,那么你会得到一个白色的屏幕。 不知道为什么这使得它的工作,但它! 视觉效果因animation而异。

所以,当我只显示肖像模态视图时遇到了同样的问题。 通常,我会创build一个UINavigationController ,将viewController设置为rootViewController ,然后将UINavigationController显示为模式视图。 但是对于iOS 6, viewController现在会要求navigationController支持它所支持的接口方向(默认情况下,它现在全部用于iPad,而其他所有方面则完全颠倒)。

解决scheme :我不得不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)子类中重写它们更安全

此外,这不包括您从横向视图推送/呈现/popup到仅肖像VC的情况,反之亦然。 为了解决这个棘手的问题(苹果从未解决),你应该:

在iOS中<= 4和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重新评估您的所有应用程序,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景观presentViewController 。 使用上面提到的方法,我能够让iPhone 5和iPhone 6工作得可以接受,但由于某种原因,iPad只是拒绝呈现为风景。 最后,我发现了一个简单的解决scheme(经过几个小时的阅读和试​​验和错误),适用于设备和ios 5&6。

步骤1)在控制器上,指定所需的方向(或多或less,如上所述)

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { NSInteger mask = UIInterfaceOrientationMaskLandscape; return mask; } 

步骤2)创build一个简单的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]; 

希望这对某人有帮助。

在这里不要沉闷,但你会如此善良地分享你的子类? 谢谢。

编辑:嗯,我终于做到了,这个子类很简单。 我只需要将AppDelegatenavigationController声明为UINavigationControllerSubclass而不是默认的UINavigationController ,然后使用以下方法修改您的子类:

 - (BOOL)shouldAutorotate { return _shouldRotate; } 

所以我可以通过调用viewDidLoad来设置我想旋转的任何视图

 _navController = (UINavigationController *)self.navigationController; [_navController setShouldRotate : YES / NO] 

希望这个调整将帮助其他人,谢谢你的提示!

提示:利用

 - (NSUInteger)supportedInterfaceOrientations 

在你的视图控制器,所以你最终没有在横向有一个肖像所需的视图,反之亦然。

我没有自己testing,但文档指出,你现在可以重写这些方法: supportedInterfaceOrientationspreferredInterfaceOrientationForPresentation

你可能可以实现你想要的只是设置你想要的方向。

使用子类或类别的答案允许UINavigationController和UITabBarController类中的VC正常工作。 从横向标签栏控制器启动仅肖像模式失败。 如果你需要这样做,那么使用显示和隐藏非animation模式视图的技巧,但在viewDidAppear方法中 。 它在viewDidLoad或viewWillAppear中并不适用于我。

除此之外,上述解决scheme正常工作。

对于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/

我认为这是充分的帮助。

只需进入project.plist,然后添加支持的界面方向,然后只添加肖像(底部主页button)和肖像(顶部主页button)。

您可以根据您的项目要求添加或删除那里的方向。

谢谢

1)检查你的项目设置和info.plist,并确保只有你想要的方向被选中。

2)将以下方法添加到最顶层的视图控制器(导航控制器/ tabbar控制器)

 - (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

3)将以下方法添加到您的应用程序委托

 - (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskPortrait; } 

把它放在你不想旋转的每个ViewController的.m文件中:

 - (NSUInteger)supportedInterfaceOrientations { //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; return UIInterfaceOrientationMaskPortrait; } 

在这里看到更多的信息。