shouldAutorotateToInterfaceOrientation未在iOS 6中调用


7 Answers

好吧,我让它在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中)

Question

我正在使用MGSplitViewController,我正在使用shouldAutorotateToInterfaceOrientation来控制旋转时主视图控制器的大小。

它在iOS 5上运行良好,但在iOS 6(模拟器和iPad)上,永远不会调用shouldAutorotateToInterfaceOrientation

这是一个我应该期望在iOS 6的最终版本中修复的错误或者我不知道已经改变的东西吗?




这适用于iOS6和Xcode 4.5 GM:

在AppDelegate.m上

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

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

    [window setRootViewController:navigationController];

    .....

    return YES;
}

在ViewController上:

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

{
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation))

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



Apple已弃用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);



虽然许多响应都指出了解决方案 - 要实现iOS 6构建的shouldAutorotate和supportedInterfaceOrientations,但您还应该知道,如果您的视图控制器托管在导航控制器中,那么它们都不重要,因为运行时将在UINavigationController实例上调用它们,否则忽略您的代码。

显然,'解决方案'是子类UINavigationController并在这个子类上实现这些新方法,如下所述: iOS 6 UITabBarController支持使用当前UINavigation控制器的方向

然后您可以更改所有代码,使用UINavigationController来代替使用这个新的子类。

这必须是我见过的iOS版本中最无意义和烦人的突破性变化之一。




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

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

    return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}



这是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;
}



事实证明,只有根视图处理这些调用。 在我的例子中,这是一个普通的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];
        }
}



以下是Apple的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: method。

- (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,请查看Vladimir的答案 。






Related