iOS6:支持的接口方向不起作用(被调用,但界面仍旋转)



在我的应用程序中,我有多个视图,有些视图需要同时支持纵向和横向,而其他视图只需要支持纵向。 因此,在项目摘要中,我选择了所有方向。

以下代码用于在iOS 6之前的给定视图控制器上禁用横向模式:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

由于 shouldAutorotateToInterfaceOrientation 在 iOS6 中被弃用,我将上述内容替换为:

-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMask.Portrait;
}

当视图出现时,可以正确调用此方法(我可以设置断点以确保这一点),但无论我只返回纵向模式的蒙版,界面仍会旋转到横向模式。 我做错了什么?

目前似乎无法构建每个视图具有不同方向要求的应用程序。 它似乎只遵循项目摘要中指定的方向。

如果你使用UINavigationController 作为根窗口控制器,它将调用它的shouldAutorotate&supportedInterfaceOrientations

如果您使用的是UITabBarController,则为 Idem,依此类推。

因此,要做的是对您的导航/标签栏控制器进行子类化并覆盖其shouldAutorotatesupportedInterfaceOrientations方法。

尝试在 AppDelegate.m 中更改此代码

//   self.window.rootViewController = self.navigationController;
[window setRootViewController:navigationController];

这是完整的答案

应该自动旋转到界面方向在 iOS 6 中未调用

鑫达

就我而言,我里面有UINavigationController和我的视图控制器。我必须对UINavigationController进行子类化,为了仅支持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

完成此操作后,方向应再次开始工作。

Ray Wenderlich 团队在 "iOS6 By Tutorials" 中特别指出了 iOS6 的最佳方法——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;
}

正如其他人所说,如果您使用的是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;
}

基本上正如上面有人所说,但更详细:

  1. 创建一个作为 UINavigationController 子类的新文件
  2. 转到情节提要,然后单击导航控制器,将其类设置为刚刚创建的类
  3. 在 class(.m 文件中),添加以下代码,使其保持纵向模式:

    (BOOL)shouldAutorotate
    {
    return NO;
    } 
    (NSUInteger)supportedInterfaceOrientations
    {
    return UIInterfaceOrientationMaskPortrait;
    }
    

这对我有用

这段代码对我有用:

-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}

iPhone/iPad应用程序方向查看我自己的答案

我认为最好的方法是做一个类别,而不是子类化UINavigationControllerUITabbarController

你的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。但我建议您从这里返回 true 并在supportedInterfaceOrientations方法中指定正确的方向。

我和你有同样的情况。 我知道你已经接受了答案,但我想无论如何我都会添加另一个答案。 这就是我理解新版本轮换系统工作的方式。 根视图控制器是唯一被调用的视图控制器。 我相信,原因是对于子视图控制器,旋转它们的视图通常没有意义,因为它们无论如何都会停留在根视图控制器的框架内。

那么,会发生什么。 在根视图控制器上调用第一个shouldAutorotate。 如果返回NO则一切都停止。 如果返回YES则调用supportedInterfaceOrientations方法。 如果在此方法中确认了界面方向,并且来自 Info.plist 或应用程序委托的全局支持方向,则视图将旋转。 在旋转之前,将查询shouldAutomaticallyForwardRotationMethods方法。 如果YES(默认值),则所有子项都将接收willdidRotateTo...方法以及父项(它们又会将其转发给子项)。

我的解决方案(直到有更雄辩的解决方案)是在supportedInterfaceOrientations方法期间查询最后一个子视图控制器并返回其值。 这让我可以旋转某些区域,同时仅保留其他区域的纵向。 我意识到它很脆弱,但我看不到另一种不涉及通过事件调用、回调等使事情复杂化的方法。

如果你使用的是UINavigationController,你必须在UINavigationController的子类中实现shouldAutorotatesupportedInterfaceOrientations

这些能够通过两个步骤进行控制,如果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

我的解决方案:子类化UINavigationController并将其设置为window.rootViewController

层次结构的顶部视图控制器将控制方向,一些代码示例:

这里的答案为我指明了正确的方向,尽管我无法通过剪切和粘贴来使其工作,因为我在UITabBarController中使用UINavigationController。 所以我在 AppDelegate.m 中的版本看起来像这样,它将适用于 UITabBarController 中的 UITabBarControllers、UINavigationController 或 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子类中的支持的接口方向,否则它将默认为您在Info.plist中指定的内容。

最新更新