shouldAutorotateToInterfaceOrientation不会被调用在iOS 6中

2019-06-18 00:09发布

我使用MGSplitViewController和我使用shouldAutorotateToInterfaceOrientation来控制上旋转的主视图控制器的大小。

这是在iOS 5,但在iOS 6(包括模拟器和iPad)所有工作正常shouldAutorotateToInterfaceOrientation永远不会被调用。

这是我应该会固定与iOS 6的最终版本或东西,我不知道发生了变化中的错误?

Answer 1:

请仔细阅读本或者你可以失去你的生活1-2天,将坚果和战斗,摇,把你的测试设备,如其中一个抓住访客的移动动物园黑猩猩! 迟早...答应:)

在iOS 6中

shouldAutorotateToInterfaceOrientation:

已过时,通过替换

shouldAutorotate

这意味着iOS 6中绝不会叫shouldAutorotateToInterfaceOrientation

所以,如果你使用的应用程序中的以下

BEFORE iOS6的(iOS5的,iOS4的等)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
// your code for portrait mode

}

return YES;
}

你应该使用

的iOS 6+

- (BOOL)shouldAutorotate {

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

if (orientation == UIInterfaceOrientationPortrait) {
// your code for portrait mode

}

return YES;
}

意识到

UIInterfaceOrientation是的性质UIApplication和只包含4种可能性,其对应于状态条的方向:

UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,

UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,

UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,

UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft

不要混淆其与

UIDeviceOrientation其是的属性UIDevice类,并含有7个可能的值:

UIDeviceOrientationUnknown - Can not be determined

UIDeviceOrientationPortrait - Home button facing down

UIDeviceOrientationPortraitUpsideDown - Home button facing up

UIDeviceOrientationLandscapeLeft - Home button facing right

UIDeviceOrientationLandscapeRight - Home button facing left

UIDeviceOrientationFaceUp - Device is flat, with screen facing up

UIDeviceOrientationFaceDown - Device is flat, with screen facing down

甚至可以使用理论上UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 返回UIDeviceOrientation -设备实际方向-但你要知道, UIDeviceOrientation并不总是等于UIInterfaceOrientation ! 例如,当你的设备是一个普通的表,你可以收到意想不到的价值。

您可以使用UIInterfaceOrientation orientation = self.interfaceOrientation; 太返回UIInterfaceOrientation ,接口的电流方向,但它的属性UIViewController ,这样你就可以访问到这一个只在UIViewController的类。

如果你想支持前iOS6的(IOS3 / 4/5)和iOS6的设备-这可能是显而易见的-只使用两个shouldAutorotateToInterfaceOrientation:shouldAutorotate在你的代码。

从iOS 6中有3个级别和3个步骤,应用程序启动时的设备检查,你必须控制它,如果你愿意的话。

1. Info.plist - Supported Interface Orientations

其中,你可以在摘要选项卡设置图形。 允许方位的顺序很重要,您可以通过编辑手动更改info.plist ,设备会选择当应用程序正在启动第一个吧! 这是因为问题总是推出的应用程序的关键时则存在机会[UIDevice currentDevice].orientation是未知的,尤其是当我们测试在一个平面上我们的应用程序。

要知道没有与(新iPad)其他两个设置可能性或(iPhone)的扩展,如果你使用其中任何一个,它将使用目前的设备或模拟器和忽视的常规设置的该设置不带扩展名。 所以,如果你运行一个只有iPhone应用程序和意外你留下了“支持的界面取向(新iPad)”行中的某处plist中,即使没有任何数据,它会忽略您在常规设置较早建立的规则(在我的例子为iPhone ),你可以得到一个拒绝你的应用程序与文本“我们发现,您的应用程序不符合要求iPad上运行......”就算你的应用程序不打算在iPhone上使用给定的方向,但iPad的将使用它可能导致不可预知的错误,所有的iPhone应用程序都在iPad上在提交过程中也运行。

2. AppDelegate - application:supportedInterfaceOrientationsForWindow

返回每次你想允许,其覆盖的info.plist settings.This方向的位掩码上市每次设备旋转称为至少一次。

3. Top-level view controller or RootViewController - supportedInterfaceOrientations

这使与该组应用程序和应用程序的委托,其具有成具有非零结果,以避免碰撞的交集。 这被称为至少一次次的装置转动时,除了没有安装在我们的控制器的另一种方法:

shouldAutorotate

与应用程序的许可方位干扰,并给出了一个BOOL默认YES

BE CAREFUL when you use `NavigationController`

在你最上面的控制器AppDelegate ,像这样的:

DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:detailViewController];
self.window.rootViewController =nil;
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;

在这种情况下,你必须把你的下面的代码AppDelegate为一类附件NavigationController类,因为这是最上面的控制器,并且如果你还没有做它的一个子类,你没有地方/代码,您可以设置其方向设置,所以你需要迫使它来检查你的真实rootViewController在这种情况下, detailViewController的方向:

@implementation UINavigationController (OrientationSettings_IOS6)

-(BOOL)shouldAutorotate {
return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations {
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

在这之后,你可以在设置首选方向你的“层次最高的” ViewController (在我的例子,这是detailViewController )与您有任何的可在iOS 6中的方法ViewControllers ,如下图所示:

1. (BOOL)shouldAutorotate

2. (NSUInteger)supportedInterfaceOrientations

3. (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation


Answer 2:

好吧,我知道了在iOS6的的iPad模拟器工作。 好极了。 这是我做的:

我只是告诉你之前和之后,它应该是不言而喻的:

之前

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

if (interfaceOrientation==UIInterfaceOrientationPortrait) {
 // do some sh!t

}

return YES;
}

- (BOOL)shouldAutorotate {

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];

if (orientation==UIInterfaceOrientationPortrait) {
 // do some sh!t

}

return YES;
}

至于支持的方向,您可以指定在info.plist中这样:

或者用代码:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait; // etc
}

编辑:关于第二个想法,如果你打算以支持低版本(的iOS4.3 / 5 / 5.1)以及6.0然后就包括代码相同的内容这两种方法。 工作对我来说(在SIM反正)



Answer 3:

设置应用程序窗口路由控制器,而不是,只是增加它的观点,作为一个子视图工作对我来说(如Rocotilos一样)

//    [self.window addSubview:self.topLevelNavigationController.view];
self.window.rootViewController = self.topLevelNavigationController;


Answer 4:

下面是iOS 5及前面的代码,不涉及重复你的逻辑的解决方案。 只需将此代码添加到您的视图控制器,并将其从现有的shouldAutorotateToInterfaceOrientation方法生成supportedInterfaceOrientations。

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{
NSInteger mask = 0;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeRight])
    mask |= UIInterfaceOrientationMaskLandscapeRight;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeLeft])
    mask |= UIInterfaceOrientationMaskLandscapeLeft;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationPortrait])
    mask |= UIInterfaceOrientationMaskPortrait;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationPortraitUpsideDown])
    mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
return mask;
}


Answer 5:

速战速决对我来说是我的根视图控制器中添加此代码

- (BOOL)shouldAutorotate {
    return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}

这样,我仍然使用之前到iOS 6中使用的版本相同的逻辑。当然,我原本设置我的RootViewController的在我的应用程序代表didFinishLaunchingWithOptions,而不是正常的只是添加到Windows子视图。



Answer 6:

虽然一些的答复有解决方案表示 - 这是实现shouldAutorotate和supportedInterfaceOrientations为iOS 6的构建 - 你也应该知道,如果你的视图控制器的导航控制器托管那么它没有一个会因为此事运行时将调用这些对UINavigationController的实例,否则忽略你的代码。

显然,“解决方案”是继承的UINavigationController和执行这个子类,这些新的方法如下所述: iOS 6中的UITabBarController支持方向与电流UINavigation控制器

然后,你必须改变所有的代码,你用一个UINavigationController使用这个新的子类,而不是乐趣。

这必须是在一个IOS版本是我所见过的最没有意义和恼人的磨合变化之一。



Answer 7:

IOS 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
if (UIInterfaceOrientationLandscapeLeft) {
        return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
    }
    if (UIInterfaceOrientationLandscapeRight) {
        return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
    }
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

IOS 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations:(UIWindow *)window{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2


    //    return UIInterfaceOrientationMaskLandscape;
    return 24;
}


Answer 8:

这为我工作与iOS6的和Xcode的4.5 GM:

在AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    .....

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

    [window setRootViewController:navigationController];

    .....

    return YES;
}

在视图控制器:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration

{
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation))

    {
      // landscape
    }
    else
    {
      //portrait
    }
}


Answer 9:

下面是苹果的iOS SDK报价,XCode4.5 +(见UIViewController类参考,处理视图旋转):

在iOS 6中,您的应用支持在应用程序的Info.plist文件中定义的接口方向。 视图控制器可以重写supportedInterfaceOrientations方法,以限制支撑取向的列表。 通常, 系统调用此方法只对窗口或呈现以填充整个屏幕的视图控制器的根视图控制器 ; 子视图控制器通过他们的父视图控制器使用为他们提供了窗口的部分,不再直接参与什么旋转,支持决策。

另外在iOS6的,shouldAutorotateToInterfaceOrientation:UIViewController类的方法已经过时了。

因此,在你的根视图控制器,你做的FF:

- (BOOL)shouldAutorotate {
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
  return UIInterfaceOrientationMaskPortrait;
}

顺便说一句,“根视图控制器”是你设为您的appDelegate的窗口对象的RootViewController的任何UIViewController子类。 你通常做在的appDelegate的应用中:didFinishLaunchingWithOptions:方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  // Override point for customization after application launch.
  self.window.rootViewController = [FFDashboardController create];
  [self.window makeKeyAndVisible];
  return YES;
}

至于使用的UINavigationController作为根VC的,结账弗拉基米尔的答案 。



Answer 10:

为了应对@Rocotilos,我有发生在我的代码,我已经没有在论坛上看到其他地方的附录。 我遇到了一个情况:在应用程序的生命周期,其中取向没有在shouldAutorotate方法已知的最开始。 这是会导致应用无法在景观正确显示视图。 在模拟器中的几个旋转后,它是工作的罚款。

我的情况是,有一些得到弹出关于我们想景观布置一定的看法。 因此,我们不希望shouldAutorotate返回YES。 我知道这可能是一些罕见的情况,但我已经花了大量的时间诊断这一点,并希望传递下去。 希望这是有帮助的。

- (BOOL) shouldAutorotate {

    BOOL shouldRotate = NO;
    UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];

    if ([self IsCaseWhereWeDontWantLandscapeAutorotation]) {
        shouldRotate = NO;
    } else if (orientation == UIDeviceOrientationUnknown) {
        //Handle the case where the device's orientation is not yet known
        shouldRotate = YES;
    } else {
        //Handle the normal case
        shouldRotate = (orientation == UIInterfaceOrientationMaskLandscape);
    }

    return shouldRotate;
}


Answer 11:

事实证明,只有根视图处理这些调用。 在我的情况下,这是一个正常的UINavigationController。 我曾在那里我加入了这个方法改变为子类的文件。

在我来说,我只是想根视图的画像,其余的人像+风景。

Appdelegate.h

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    S2MBookAppRootViewController *masterViewController = [[[S2MBookAppRootViewController alloc] initWithNibName:pref.rootNibName bundle:nil] autorelease];
    self.navigationController = [[[S2MBookAppNavController alloc] initWithRootViewController:masterViewController] autorelease];

    self.window.rootViewController = self.navigationController;


    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES];

    return YES;
}

而S2MBookAppNavController(UINavigationController的子类)

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if([self.viewControllers count] == 1) return UIInterfaceOrientationMaskPortrait;
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
}

更新:当你想强制方向(导航控制器上推一个新视图时)试试这个。

让你的UINavigationController也是它自己的代表:

@interface S2MBookAppNavController : UINavigationController <UINavigationControllerDelegate>

@end

而在.m文件

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.delegate = self;
    // Do any additional setup after loading the view.
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) {
            //present/dismiss viewcontroller in order to activate rotating.
            UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
            [self presentModalViewController:mVC animated:NO];
            [self dismissModalViewControllerAnimated:NO];
        }
}


Answer 12:

是的,问题是所谓的返回方向面具只window.rootViewController方法。 所以supportedInterfaceOrientations方法必须被设置为window.rootViewController的viewController来实现。 但在大多数情况下,这个目标是自定义类,如UINavigationController的不是。 一个可能的解决方案是UINavigationController的子类。 但苹果表示:“此类不适合子类”,所以我宁愿用另一个UIViewController的处理方向和增加的UINavigationController作为孩子。

MyRootViewController * myRoot = [MyRootViewController new];
self.window.rootViewController = myRoot;
[myRoot addChildViewController:navigationController];
[myRoot.view addSubview:navigationController.view];

在MyRootViewController实现方法:

- (BOOL)shouldAutorotate {
 return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    // return your mask here e.g.:
    return UIInterfaceOrientationMaskPortrait;
}


Answer 13:

我有一系列在一个UINavigationController视图控制器,其中一个必须只能是景观。 我固定它通过继承的UINavigationController并添加以下代码:

- (NSUInteger)supportedInterfaceOrientations{
   return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

这确保了最上面的视图控制器指示的方向。

有一种疑难杂症,虽然:如果你是从仅限于景观到支持任何方向的移动VC,新视图将不考虑手机的方位显示在景观。 为了解决这个问题,我把无限viewControllers下面的代码:

- (NSUInteger)supportedInterfaceOrientations{
   if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))       
      return UIInterfaceOrientationMaskPortrait;
   else
      return UIInterfaceOrientationMaskLandscape;
}


Answer 14:

-(BOOL)shouldAutorotate
{
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;

    if (orientation == UIDeviceOrientationUnknown) {
        return YES;
    }

    return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}


Answer 15:

标题下的UIKit笔记这里: http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html%23//apple_ref/doc/uid/TP40012166-CH1- SW19提供一些线索答案,但它不是全貌。 我没有全貌还没有,但这里是我迄今为iOS 6.0 RTM发现。

如果你是不是真的限制支撑取向,相反,你想要做一些事情,因为用户旋转设备,那么您可以在移动逻辑

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

- (void)viewWillLayoutSubviews

代替。

这大概可以直接替换,但我还没有在下级的IOS版本测试过。

如果你想限制支撑取向,你应该做的是在UIApplicationDelegate水平

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

文档指出“系统确定的方位是否是由交叉的由应用的返回的值支持supportedInterfaceOrientationsForWindow:与由最上面的全屏幕控制器的supportedInterfaceOrientations方法返回的值的方法”。 但在实验中我发现,系统将忽略支持我的视图控制器

-(NSUInteger)supportedInterfaceOrientations

返回值,尽管方法被调用。



Answer 16:

从iOS6的使用这些方法,而不是苹果已经过时shouldautorate方法。 请参阅您的Xcode文档

- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0);
- (NSUInteger)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0);
// Returns interface orientation masks.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0);


Answer 17:

它的工作对我来说:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
    if ([self isKindOfClass:[YourViewController class]]) { // Your view class
        orientations |= UIInterfaceOrientationMaskPortraitUpsideDown;
    }
    return orientations;
}

方向:

orientations |= UIInterfaceOrientationMaskLandscapeLeft;
orientations |= UIInterfaceOrientationMaskLandscapeRight;


文章来源: shouldAutorotateToInterfaceOrientation not being called in iOS 6