ios iOS6:supportedInterfaceOrientations 不工作(被调用但界面仍然旋转)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12447552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:10:55  来源:igfitidea点击:

iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates)

iphoneobjective-ciosios6

提问by aneuryzm

In my app I have multiple views, some views need to support both portrait and landscape, while other views need to support portrait only. Thus, in the project summary, I have all selected all orientations.

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

The below code worked to disable landscape mode on a given view controller prior to iOS 6:

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

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

Since shouldAutorotateToInterfaceOrientation was deprecated in iOS6 I've replaced the above with:

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

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

This method is correctly called when the view appears (I can set a breakpoint to ensure this), but the interface still rotates to landscape mode regardless of the fact that I'm returning the mask for portrait modes only. What am I doing wrong?

这个方法在视图出现时被正确调用(我可以设置一个断点来确保这一点),但界面仍然旋转到横向模式,而不管我只返回纵向模式的掩码。我究竟做错了什么?

It seems that it's currently impossible to build an app that has different orientation requirements per view. It seems to only adhere to the orientations specified in the project summary.

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

回答by Martin

If your are using a UINavigationController as the root window controller, it will be itsshouldAutorotate& supportedInterfaceOrientationswhich would be called.

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

Idem if you are using a UITabBarController, and so on.

如果您使用的是UITabBarController,同上,依此类推。

So the thing to do is to subclass your navigation/tabbar controller and override its shouldAutorotate& supportedInterfaceOrientationsmethods.

所以要做的是子类化你的导航/标签栏控制器并覆盖它的shouldAutorotate&supportedInterfaceOrientations方法。

回答by NSStudent

try change this code in AppDelegate.m

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

//   self.window.rootViewController = self.navigationController;

    [window setRootViewController:navigationController];

this is the complete answer

这是完整的答案

shouldAutorotateToInterfaceOrientation not being called in iOS 6

在 iOS 6 中没有调用 shouldAutorotateToInterfaceOrientation

XD

XD

回答by Pavel

In my case I have UINavigationController and my view controller inside. I had to subclass UINavigationController and, in order to support only Portrait, add this method:

就我而言,我有 UINavigationController 和我的视图控制器。我不得不继承 UINavigationController 并且为了只支持 Portrait,添加这个方法:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

So in the UINavigationController subclass I need to check which orientation is supported by the current topViewController.

所以在 UINavigationController 子类中,我需要检查当前 topViewController 支持哪个方向。

- (NSUInteger)supportedInterfaceOrientations
{
    return [[self topViewController] supportedInterfaceOrientations];
}

回答by James Jones

One thing I've found is if you have an old application that is still doing

我发现的一件事是,如果您有一个仍在运行的旧应用程序

[window addSubView:viewcontroller.view];  //This is bad in so may ways but I see it all the time...

You will need to update that to:

您需要将其更新为:

[window setRootViewController:viewcontroller]; //since iOS 4

Once you do this the orientation should begin to work again.

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

回答by Phil

The best way for iOS6 specifically is noted in "iOS6 By Tutorials" by the Ray Wenderlich team - http://www.raywenderlich.com/and is better than subclassing UINavigationController for most cases.

Ray Wenderlich 团队在“iOS6 By Tutorials”中特别指出了 iOS6 的最佳方法 - http://www.raywenderlich.com/,并且在大多数情况下比子类化 UINavigationController 更好。

I'm using iOS6 with a storyboard that includes a UINavigationController set as the initial view controller.

我将 iOS6 与故事板一起使用,其中包含设置为初始视图控制器的 UINavigationController。

//AppDelegate.m - this method is not available pre-iOS6 unfortunately

//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 - return whatever orientations you want to support for each UIViewController

//MyViewController.m - 返回您希望为每个 UIViewController 支持的任何方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

回答by Causaelity

As stated by others if you're using a UINavigationController and you want to customize various views you'll want to subclass the UINavigationController and make sure you have these two components:

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

Then in any view that is a portrait only you would include:

然后在任何只有肖像的视图中,您将包括:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

And in any view that is everything but upside down:

从任何角度来看,这都是颠倒的:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

回答by user1601259

Basically as someone stated above, but in more detail:

基本上如上所述,但更详细:

  1. Create a new file that is a subclass of UINavigationController
  2. Go to your storyboard and then click on the Navigation Controller, set its class to the one that you just created
  3. In this class(.m file) add the following code so it will remain in portrait mode:

    (BOOL)shouldAutorotate
    {
      return NO;
    } 
    
    (NSUInteger)supportedInterfaceOrientations
    {
     return UIInterfaceOrientationMaskPortrait;
    }
    
  1. 创建一个新文件,它是 UINavigationController 的子类
  2. 转到您的故事板,然后单击导航控制器,将其类设置为您刚刚创建的类
  3. 在此类(.m 文件)中添加以下代码,使其保持纵向模式:

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

This worked for me

这对我有用

回答by Vassily

The best way I think is to do a Category rather than subclassing UINavigationControlleror UITabbarController

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

your UINavigationController+Rotation.h

你的 UINavigationController+Rotation.h

#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation)

@end

your UINavigationController+Rotation.m

你的 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

Try to make all your controller import this category and this work like a charm. You can even make a controller not rotating and pushing another controller that will rotate.

试着让你的所有控制器都导入这个类别,这就像一个魅力。您甚至可以使控制器不旋转并推动另一个将旋转的控制器。

回答by tcd

This code worked for me:

这段代码对我有用:

-(BOOL)shouldAutorotate {
     return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

iPhone/iPad App Orientationcheck out my own answer

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

回答by borrrden

I have the same situation as you. I know you already accepted an answer, but I thought I'd add another one anyway. This is the way I understand the new version of the rotation system to work. The root view controller is the only view controller to ever be called. The reasoning, I believe, is that with child view controllers it doesn't make sense often to rotate their views since they will just stay within the frame of the root view controller anyway.

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

So, what happens. First shouldAutorotateis called on the root view controller. If NOis returned then everything stops. If YESis returned then the supportedInterfaceOrientationsmethod is invoked. If the interface orientation is confirmed in this method andthe global supported orientations from either the Info.plist or the application delegate, then the view will rotate. Before the rotation the shouldAutomaticallyForwardRotationMethodsmethod is queried. If YES(the default), then all children will receive the willand didRotateTo...methods as well as the parent (and they in turn will forward it to their children).

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

My solution (until there is a more eloquent one) is to query the last child view controller during the supportedInterfaceOrientationsmethod and return its value. This lets me rotate some areas while keeping others portrait only. I realize it is fragile, but I don't see another way that doesn't involve complicating things with event calls, callbacks, etc.

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