由于ShouldAutorotateToInterfaceOrientation
iOS 6中已弃用,我使用它来强制将特定视图仅设为纵向,因此在iOS 6中执行此操作的正确方法是什么?这仅适用于我的应用程序的一个区域,所有其他视图均可旋转。
Answers:
如果您希望我们所有的导航控制器都遵守顶视图控制器,则可以使用类别,这样您就不必遍历并更改一堆类名。
@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。
Ray Wenderlich小组在“ iOS6 By Tutorials”(http://www.raywenderlich.com/)中指出了专门针对iOS6的最佳方法,它优于子类化UINavigationController
大多数情况下。
我将iOS6与故事板一起使用,其中包括 UINavigationController
组作为初始视图控制器。
//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:^{
}];
}];
}
有趣的是,在写入,时任一本或关闭必须进行动画处理。如果两者都不是,则您将获得白屏。不知道为什么这使它起作用,但是它起作用了!视效果而异,具体取决于哪个动画。
因此,在显示仅纵向模式视图时遇到了相同的问题。通常,我会创建一个UINavigationController
,将设置viewController
为rootViewController
,然后将其显示UINavigationController
为模式视图。但是在iOS 6上,viewController
现在将向navigationController询问其受支持的界面方向(默认情况下,现在全部用于iPad,除了颠倒的所有内容用于iPhone)。
解决方案:我必须UINavigationController
继承并重写自动旋转方法。有点la子。
- (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)子类中覆盖它们更安全
此外,这还不包括从“横向”视图推入/呈现/弹出到仅纵向VC或相反的情况。要解决这个棘手的问题(Apple从未解决过),您应该:
在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重新评估您所有的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只是拒绝将其显示为Landscape。最后,我找到了一个适用于设备和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];
希望这对某人有帮助。
在这里不要呆板,但您愿意分享您的子类吗?谢谢。
编辑:好吧,我终于做到了,子类很简单。我只需要navigationController
在AppDelegate
as中声明asUINavigationControllerSubclass
而不是default UINavigationController
,然后用以下代码修改您的子类:
- (BOOL)shouldAutorotate {
return _shouldRotate;
}
因此我可以通过调用来设置我想旋转或不旋转的任何视图 viewDidLoad
_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
希望这项调整对其他人也有帮助,谢谢您的提示!
提示:利用
- (NSUInteger)supportedInterfaceOrientations
在视图控制器中,这样一来,您最终就不会在横向上拥有肖像所需的视图,反之亦然。
对于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,然后添加支持的界面方向,然后仅添加Portrait(底部主页按钮)和Portrait(顶部主页按钮)即可。
您可以根据项目要求添加或删除定向。
谢谢
1)检查您的项目设置和info.plist,并确保仅选择了所需的方向。
2)将以下方法添加到最顶层的视图控制器(导航控制器/标签栏控制器)中
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
3)将以下方法添加到您的应用程序委托中
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}