iOS6:supportedInterfaceOrientations不起作用(被调用但界面仍在旋转)
在我的应用程序中,我有多个视图,一些视图需要支持纵向和横向,而其他视图只需要支持纵向。 因此,在项目总结中,我select了所有的方向。
下面的代码工作在iOS 6之前的给定视图控制器上禁用横向模式:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); }
由于shouldAutorotateToInterfaceOrientation已被弃用在iOS6我已经取代了上述:
-(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMask.Portrait; }
当视图出现时(我可以设置一个断点来确保这一点),这个方法被正确调用,但是无论我只是为了肖像模式返回蒙版,界面仍然旋转到横向模式。 我究竟做错了什么?
目前看来,目前不可能构build一个每个视图有不同定位要求的应用程序。 似乎只是坚持项目总结中指定的方向。
如果你正在使用一个UINavigationController作为根窗口控制器 ,它将是它的 shouldAutorotate
& supportedInterfaceOrientations
将被调用。
同样,如果你正在使用UITabBarController ,依此类推。
因此,要做的事情是inheritance你的导航/选项卡栏控制器,并覆盖其shouldAutorotate
& supportedInterfaceOrientations
方法。
请尝试在AppDelegate.m中更改此代码
// self.window.rootViewController = self.navigationController; [window setRootViewController:navigationController];
这是完整的答案
shouldAutorotateToInterfaceOrientation不在iOS 6中调用
XD
在我的情况下,我有UINavigationController和我的视图控制器里面。 我不得不inheritanceUINavigationController,为了只支持Portrait,添加这个方法:
- (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; }
所以在UINavigationController子类中,我需要检查当前topViewController支持哪个方向。
- (NSUInteger)supportedInterfaceOrientations { return [[self topViewController] supportedInterfaceOrientations]; }
我发现的一件事是,如果你有一个旧的应用程序,仍然在做
[window addSubView:viewcontroller.view]; //This is bad in so may ways but I see it all the time...
您需要将其更新为:
[window setRootViewController:viewcontroller]; //since iOS 4
一旦你这样做的方向应该开始工作了。
对于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; }
正如其他人所说,如果您使用的是UINavigationController,并且您想要自定义各种视图,则您需要inheritanceUINavigationController并确保您拥有以下两个组件:
@implementation CustomNavigationController // ------------------------------------------------------------------------------- // supportedInterfaceOrientations: // Overridden to return the supportedInterfaceOrientations of the view controller // at the top of the navigation stack. // By default, UIViewController (and thus, UINavigationController) always returns // UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone. // ------------------------------------------------------------------------------- - (NSUInteger)supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } // ------------------------------------------------------------------------------- // shouldAutorotate // Overridden to return the shouldAutorotate value of the view controller // at the top of the navigation stack. // By default, UIViewController (and thus, UINavigationController) always returns // YES when the app is run on an iPhone. // ------------------------------------------------------------------------------- - (BOOL)shouldAutorotate { return [self.topViewController shouldAutorotate]; }
那么在任何只有肖像的视图中,你才会包括:
- (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
而且从任何angular度来看,都是颠倒的:
- (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; }
基本上如上所述,但更详细地说:
- 创build一个新的文件,它是UINavigationController的一个子类
- 转到故事板,然后单击导航控制器,将其类设置为您刚创build的类
-
在这个类(.m文件)中,添加下面的代码,使它保持纵向模式:
(BOOL)shouldAutorotate { return NO; } (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
这对我有效
这段代码适用于我:
-(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; }
iPhone / iPad应用程序的方向检查我自己的答案
我认为最好的办法是做一个类别,而不是UITabbarController
UINavigationController
或UITabbarController
你的UINavigationController + Rotation.h
#import <UIKit/UIKit.h> @interface UINavigationController (Rotation) @end
你的UINavigationController + Rotation.m
#import "UINavigationController+Rotation.h" @implementation UINavigationController (Rotation) -(BOOL)shouldAutorotate { return [[self.viewControllers lastObject] shouldAutorotate]; } -(NSUInteger)supportedInterfaceOrientations { return [[self.viewControllers lastObject] supportedInterfaceOrientations]; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation]; } @end
试着让所有的控制器导入这个类别,这个工作就像一个魅力。 你甚至可以让一个控制器不旋转,并推动另一个将旋转的控制器。
尝试添加shouldAutorotate
方法
首先,为了使你的应用程序只在模式下工作,你应该返回UIInterfaceOrientationMaskLandscape
。 如果你只想保持肖像模式,你正在做的事情正确。
只需在Info.plist中添加UISupportedInterfaceOrientations
项并分配您的应用程序想要保留的界面方向值即可。
另外,如果你想完全避免自动旋转,你应该从shouldAutoRotate
返回false。 但是我build议你从这里返回true,并在supportedInterfaceOrientations
方法中指定正确的方向。
我和你有同样的情况。 我知道你已经接受了一个答案,但我想我会再添加一个答案。 这是我理解新版本的轮换系统的工作方式。 根视图控制器是唯一被调用的视图控制器。 推理,我相信,对于子视图控制器来说,经常旋转视图是没有意义的,因为它们将始终保持在根视图控制器的框架内。
那么,会发生什么。 首先应该在根视图控制器上调用shouldAutorotate
。 如果NO
返回,则一切都停止。 如果返回YES
则调用supportedInterfaceOrientations
方法。 如果在此方法中确认了界面方向, 并从Info.plist或应用程序委托中全局支持方向,则视图将旋转。 在旋转之前查询shouldAutomaticallyForwardRotationMethods
方法。 如果YES
(默认),那么所有的孩子都会收到will
和didRotateTo...
方法以及父母(他们又将它们转发给他们的孩子)。
我的解决scheme(直到有一个更有说服力的)是在supportedInterfaceOrientations
方法中查询最后一个子视图控制器并返回它的值。 这让我旋转一些地区,而只保留其他人像。 我意识到这是脆弱的,但我没有看到另一种不涉及与事件调用,callback等事情复杂的方式。
如果您使用的是UINavigationController
,则必须在UINavigationController
子类中实现shouldAutorotate
和supportedInterfaceOrientations
。
如果shouldAutorotate
返回YES,则有效的supportedInterfaceOrientations
。 这是一个非常好的组合。
这个例子中,我主要的意见是除了CoverFlowView和PreviewView之外的肖像。 CoverFlowView传输到PreviewView,PreviewView想要跟随CoverFlowCView的旋转。
@implementation MyNavigationController -(BOOL)shouldAutorotate { if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")]) return NO; else return YES; } -(NSUInteger)supportedInterfaceOrientations { if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")]) return UIInterfaceOrientationMaskAllButUpsideDown; else return UIInterfaceOrientationMaskPortrait; } ... @end
我的解决scheme:子类UINavigationController
并将其设置为window.rootViewController
层次结构的顶层viewcontroller将取得方向的控制,一些代码示例: subclassed UINavigationController
这里的答案指出我在正确的方向,虽然我不能通过剪切和粘贴来工作,因为我在UITabBarController中使用UINavigationControllers。 所以我在AppDelegate.m中的版本看起来像这样,它可以用于UITabBarController中的UITabBarControllers,UINavigationControllers或UINavigationControllers。 如果您正在使用其他自定义包容控制器,则需要在此处添加它们(这是一种令人失望的)。
- (UIViewController*)terminalViewController:(UIViewController*)viewController { if ([viewController isKindOfClass:[UITabBarController class]]) { viewController = [(UITabBarController*)viewController selectedViewController]; viewController = [self terminalViewController:viewController]; } else if ([viewController isKindOfClass:[UINavigationController class]]) { viewController = [[(UINavigationController*)viewController viewControllers] lastObject]; } return viewController; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { NSUInteger orientations = UIInterfaceOrientationMaskPortrait; UIViewController* viewController = [self terminalViewController:window.rootViewController]; if (viewController) orientations = [viewController supportedInterfaceOrientations]; return orientations; }
另一个需要注意的关键是你必须在你的UIViewController子类中重写supportedInterfaceOrientations,否则它将默认为你在Info.plist中指定的内容。