14

我做了一个基于标签的应用程序。什么都不需要在横向模式下,只需要几个视图。它在 iOS5 上运行良好,我对结果非常满意。然而,使用 iOS6 并且没有弄乱任何东西,它现在会旋转所有视图,结果并不好。

因为它是一个基于选项卡的应用程序,所以我在横向中需要的几个视图是 modalViews。这样我就不会弄乱标签栏,我只需要在构建选项的“支持的方向”设置中选择肖像并设置:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

关于我想要的风景。

现在有了 iOS6,这个视图也处于纵向模式,无论如何,即使我旋转设备,它们也不会显示横向模式。同样,如果我允许“支持的方向”上的所有方向,它们都会旋转,无论我在上面的方法中使用什么。

在所有视图中,我都没有选中情节提要上的“使用自动布局”框。

这里有什么帮助吗?

*编辑** 现在我看到了,我在设备上的应用程序运行良好。我已经安装了促销代码,而不是来自 Xcode,只是为了查看我的客户是否有问题。幸运的是,他们不是。但问题仍然存在。

4

12 回答 12

36

我为这个问题找到的文档中最重要的部分是:

当用户更改设备方向时,系统会在根视图控制器或填充窗口的最顶部呈现的视图控制器上调用此方法

为了使我的应用程序在 iOS 6 中完全可以自动旋转,我必须执行以下操作:

1)我创建了一个新的UINavigationController子类,并添加了shouldAutorotate和supportedInterfaceOrientation方法:

// MyNavigationController.h:
#import <UIKit/UIKit.h>

@interface MyNavigationController : UINavigationController

@end

// MyNavigationController.m:
#import "MyNavigationController.h"
@implementation MyNavigationController
...
- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}
...
@end

2)在 AppDelegate 中,我确实使用了我的新子类来显示我的根 ViewController(它是 introScreenViewController,一个 UIViewController 子类)并且确实设置了 self.window.rootViewController,所以看起来:

    nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
    nvc.navigationBarHidden = YES;
    self.window.rootViewController = nvc;
    [window addSubview:nvc.view];
    [window makeKeyAndVisible];
于 2012-09-22T03:11:54.053 回答
10

如果您使用标签栏控制器,这是iOS6的替代解决方案。它还表明不需要覆盖 UINavigationController 甚至 UITabBarController。

在你的xyzAppDelegate.h添加这个接口:

@interface UITabBarController (MyApp)
@end

并在xyzAppDelegate.m添加这些方法:

@implementation UITabBarController (MyApp) 

-(BOOL)shouldAutorotate
{
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
  // your custom logic for rotation of selected tab
  if (self.selectedIndex==...) {
    return UIInterfaceOrientationMaskAll;
  } 
  else {
    return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
  }
}

@end

此外,为应用程序窗口设置根视图控制器:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...
  [self.window setRootViewController:tabBarController];
于 2012-09-24T10:57:34.130 回答
6

您是否在委托中设置了 rootViewController?例如,

    self.window.rootViewController = self.navigationController;

当我进行一些 iOS6 测试时,它无法正常工作,直到我这样做......

于 2012-09-21T19:17:11.960 回答
5

对于跨 5.0 到 6.0 的工作,我有一个很好的解决方案 - 以上所有内容

-(BOOL)shouldAutorotate{return [self shouldIRotateAnyiOS];}//iOS6

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return [self shouldIRotateAnyiOS];}//pre iOS6

-(BOOL)shouldIRotateAnyiOS{
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
//do the rotation stuff
return YES
}
于 2012-10-04T05:08:47.530 回答
1

您可能会仔细检查支持接口方向

在此处输入图像描述

在以前的版本中,它没有任何意义,但现在会影响整个应用程序。

注意:即使在 iOS 6 上启用或禁用,“倒置”选项也不起作用。

于 2012-09-26T09:22:37.767 回答
1

这对我有用。

我创建了一个新的 UINavigationController 子类,并添加了 shouldAutorotate 和 supportedInterfaceOrientation 方法:

#import "MyNavigationController.h"

@interface MyNavigationController ()

@end

@implementation MyNavigationController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

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

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

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

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

@end

然后将此添加到您的委托

UINavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:_viewController];
nvc.navigationBarHidden = NO; // YES if you want to hide the navigationBar
self.window.rootViewController = nvc;
[_window addSubview:nvc.view];
[_window makeKeyAndVisible];

现在您可以将其添加到要在所有方向上旋转的视图中

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

或者将此添加到您只想进行纵向和纵向颠倒的视图中

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return
    (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}

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

- (BOOL)shouldAutorotate
{
    return YES;
}
于 2012-11-07T10:08:38.667 回答
0

此代码适用于 ios5 和 ios6

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
        [self performSelector:@selector(setframeLandscap) withObject:nil afterDelay:0.2];
    }
    else {
        [self performSelector:@selector(setframePortrait) withObject:nil afterDelay:0.2];
    }
}

-(BOOL)shouldAutorotate {    
    return YES;
}
于 2012-09-26T08:34:36.463 回答
0

做了一些实验:获取一个现有的应用程序(在 iOS-6 中不会旋转,但以前会旋转)并将一行添加self.window.rootViewController = navCtlr;到 AppDelegate。这导致应用程序看起来(至少乍一看)旋转得很好。

然后,出于好奇,我创建了 RotationCanary 类并将其实例插入 self.window.rootViewController。我会启动应用程序并等待不可避免的“无法识别的选择器”,在 RotationCanary 中创建该名称的新方法,然后重新运行。新方法将调用真正的nav ctlr 并在返回之前记录其响应。这产生了(比我预期的要早)以下日志:

2012-12-07 13:08:47.689 MyTestApp[53328:c07] System Version is 6.0;    Supported versions are 5.0.x to 6.0.x
2012-12-07 13:08:47.691 MyTestApp[53328:c07] Host memory (in bytes) used: 3489513472 free: 803893248 total: 4293406720
2012-12-07 13:08:47.692 MyTestApp[53328:c07] Memory in use by task (in bytes): 23719936
2012-12-07 13:08:47.695 MyTestApp[53328:c07] Creating database
2012-12-07 13:08:47.699 MyTestApp[53328:c07] Item Selected: (null)  (null)
2012-12-07 13:08:47.700 MyTestApp[53328:c07] <DetailViewController.m:(27)> Entering Method -[DetailViewController viewDidLoad]
2012-12-07 13:08:47.706 MyTestApp[53328:c07] <SplitContentViewController.m:(57)> Entering Method -[SplitContentViewController viewDidLoad]
2012-12-07 13:08:47.708 MyTestApp[53328:c07] <FamilyMasterViewController.m:(32)> Entering Method -[FamilyMasterViewController viewDidLoad]
2012-12-07 13:08:47.709 MyTestApp[53328:c07] <MasterViewController.m:(41)> Entering Method -[MasterViewController viewDidLoad]
2012-12-07 13:08:47.718 MyTestApp[53328:c07] <FamilyHomeDetailViewController.m:(51)> Entering Method -[FamilyHomeDetailViewController viewDidLoad]
2012-12-07 13:08:47.820 MyTestApp[53328:c07] -[RotationCanary _preferredInterfaceOrientationGivenCurrentOrientation:] - current = 2, result = 2
2012-12-07 13:08:47.821 MyTestApp[53328:c07] -[RotationCanary _existingView] - view = (null)
2012-12-07 13:08:47.824 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary wantsFullScreenLayout] - result = YES
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = <UIWindow: 0x9c76320; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x9c76450>>, result = YES
2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result = <SignOnViewController: 0x9c942a0>
2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64

奇怪的是,该类实际上从未被调用来执行旋转——仅在设置期间。

我怀疑Apple 使用 rootViewController 的设置纯粹是为了表明该应用程序已针对 iOS 6 旋转进行了修改——否则它没有真正的功能。

FWIW:我突然想到调用者可能正在使用respondsToSelector和跳过一些调用,所以我添加了resolveInstanceMethod:RotationCanary 的实现,以捕获任何此类尝试。没有发生。

于 2012-12-07T19:25:38.670 回答
0

您可能需要处理一些事情才能使其正常工作,因为在 iOS6 中,自动旋转的结构发生了变化。现在反转了如何确定自转的结构。过去,单个视图控制器可以通过其决定控制自动旋转,但现在“shouldAutorotate”由导航中的最高父级确定,在您的情况下是 tabBar。

  1. 您需要确保您的窗口设置了 rootViewController 而不仅仅是作为子视图添加。
  2. 您可能需要将 tabBarController 子类化以实现“supportedInterfaceOrientations”和“shouldAutorotate”。
  3. 如果有任何 viewController 需要采取不同的行为,那么您需要让 tabBarController 与他们协商以了解它们是否应该自动旋转的答案。

例如:

- (BOOL)shouldAutorotate
{
    return self.selectedViewController.shouldAutorotate;
}

在您的视图控制器中,您将实现 shouldAutorotate 并在那里做出决定。

于 2012-09-21T20:58:41.500 回答
0

对于 iOS6 上的应用程序“相同图片”,我需要更改方向,我的 UIViewController 永远不会被告知方向,它是一个照片叠加层,可能效果很好:

- (void)didRotate: ( NSNotification* )note
{
    [self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}

我通过延迟通话进行了精细的尺寸调整。从通知很容易知道最终方向

于 2012-11-01T10:05:14.003 回答
0

来自 Apple 的 shouldAutorotateToInterfaceOrientation 文档:

改写supportedInterfaceOrientations 和preferredInterfaceOrientationForPresentation 方法。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instm/UIViewController/shouldAutorotateToInterfaceOrientation

于 2012-10-13T09:16:49.120 回答
0

iOS 6.0 中的自动旋转发生了变化。检查此链接以获取更多信息。

iOS 6 中的自动旋转正在发生变化。在 iOS 6 中,不推荐使用 UIViewController 的 shouldAutorotateToInterfaceOrientation: 方法。取而代之的是,您应该使用 supportedInterfaceOrientations 和 shouldAutorotate 方法。

于 2012-09-21T19:11:50.617 回答