在我的应用中,我有多个视图,一些视图需要同时支持纵向和横向,而其他视图只需要支持纵向。因此,在项目摘要中,我已经选择了所有方向。
以下代码用于在iOS 6之前禁用给定视图控制器上的横向模式:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
由于在iOS6中弃用了shouldAutorotateToInterfaceOrientation,我已将上述内容替换为:
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMask.Portrait;
}
当视图出现时我会正确调用此方法(我可以设置断点以确保这一点),但是界面仍然会旋转到横向模式,而不管我是否只为纵向模式返回蒙版。我做错了什么?
目前似乎无法构建每个视图具有不同方向要求的应用。它似乎只遵循项目摘要中指定的方向。
答案 0 :(得分:69)
如果您使用 UINavigationController作为根窗口控制器,它将 shouldAutorotate
& supportedInterfaceOrientations
将会被召唤。
如果您使用的是 UITabBarController ,请注意等等。
所以要做的是将您的导航/标签栏控制器子类化并覆盖其shouldAutorotate
& supportedInterfaceOrientations
方法。
答案 1 :(得分:30)
尝试在AppDelegate.m中更改此代码
// self.window.rootViewController = self.navigationController;
[window setRootViewController:navigationController];
这是完整的答案
shouldAutorotateToInterfaceOrientation not being called in iOS 6
XD
答案 2 :(得分:20)
在我的情况下,我有UINavigationController和我的视图控制器。我不得不继承UINavigationController,为了只支持Portrait,添加这个方法:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
所以在UINavigationController子类中,我需要检查当前topViewController支持哪个方向。
- (NSUInteger)supportedInterfaceOrientations
{
return [[self topViewController] supportedInterfaceOrientations];
}
答案 3 :(得分:15)
我发现有一件事是你有一个旧的应用程序还在做什么
[window addSubView:viewcontroller.view]; //This is bad in so may ways but I see it all the time...
您需要将其更新为:
[window setRootViewController:viewcontroller]; //since iOS 4
一旦你这样做,方向应该开始重新开始。
答案 4 :(得分:14)
对于iOS6,最好的方法是在Ray Wenderlich团队的“iOS6 By Tutorials”中注明 - http://www.raywenderlich.com/并且在大多数情况下都比为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;
}
答案 5 :(得分:10)
正如其他人所说,如果您正在使用UINavigationController并且想要自定义各种视图,那么您需要将UINavigationController子类化,并确保您拥有这两个组件:
@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;
}
并且在任何观点中都是颠倒过来的一切:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
答案 6 :(得分:2)
基本上如上所述,但更详细:
在此类(.m文件)中添加以下代码,使其保持纵向模式:
(BOOL)shouldAutorotate
{
return NO;
}
(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
这对我有用
答案 7 :(得分:1)
此代码对我有用:
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
iPhone/iPad App Orientation查看我自己的答案
答案 8 :(得分:1)
我认为最好的方法是做一个类别而不是子类化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
尝试让所有控制器导入此类别,这就像魅力一样。 您甚至可以使控制器不旋转并按下另一个将旋转的控制器。
答案 9 :(得分:0)
尝试添加shouldAutorotate
方法
答案 10 :(得分:0)
首先,为了让您的应用仅以模式运行,您应该返回UIInterfaceOrientationMaskLandscape
。如果你想只保留肖像模式,你就是在正确地做事。
只需在Info.plist中添加UISupportedInterfaceOrientations
键,然后指定应用程序打算保留的界面方向值。
另外,如果你想完全避免自动轮换,你应该从shouldAutoRotate
返回false。但我建议你从这里返回true并在supportedInterfaceOrientations
方法中指定正确的方向。
答案 11 :(得分:0)
我和你有同样的情况。我知道你已经接受了答案,但我想我还要加一个答案。这是我理解新版旋转系统的工作方式。根视图控制器是唯一可以调用的视图控制器。我认为,推理的原因在于,对于子视图控制器来说,旋转视图通常没有意义,因为它们只会保留在根视图控制器的框架内。
那么,会发生什么。首先shouldAutorotate
在根视图控制器上称为 。如果返回NO
,那么一切都会停止。如果返回YES
,则调用supportedInterfaceOrientations
方法。如果在此方法中确认了界面方向和来自Info.plist或应用程序委托的全局支持方向,则视图将旋转。在轮换之前,查询shouldAutomaticallyForwardRotationMethods
方法。如果YES
(默认值),那么所有孩子都会收到will
和didRotateTo...
方法以及父级(他们会将其转发给孩子)。
我的解决方案(直到有一个更有说服力的解决方案)是在supportedInterfaceOrientations
方法期间查询最后一个子视图控制器并返回其值。这让我可以旋转一些区域,同时只保留其他区域。我意识到它很脆弱,但是我没有看到另外一种不涉及事件调用,回调等问题的方法。
答案 12 :(得分:0)
如果您使用UINavigationController
,则必须在shouldAutorotate
的子类中实施supportedInterfaceOrientations
和UINavigationController
。
如果shouldAutorotate
返回YES然后生效supportedInterfaceOrientations
,则可以通过两个步骤进行控制。这是一个非常好的组合。
这个例子,除了CoverFlowView和PreviewView之外,我的大多数视图都是Portrait。 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
答案 13 :(得分:0)
我的解决方案:子类UINavigationController
并将其设置为window.rootViewController
层次结构的顶层视图控制器将控制方向,一些代码示例: subclassed UINavigationController
答案 14 :(得分:0)
这里的答案指出了我正确的方向,虽然我不能通过剪切和粘贴来使它工作,因为我在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中指定的内容。