【问题标题】:navigationController pushed ViewControllers won't autorotateuinavigationController push View Controllers 不会自动旋转
【发布时间】:2011-09-29 22:15:21
【问题描述】:

我很难让导航控制器正确自动旋转。显示将在初始视图(根视图控制器)上自动旋转,但不会在任何被推送的新视图上旋转。它保持初始视图在推送时的视图方向。

在我的 App Delegate 中,我有一个导航控制器并推送它的视图。

[window addSubview:navigationController.view];
[window makeKeyAndVisible];

在根视图控制器中,我允许所有方向,并将其他视图推送到控制器的堆栈中。

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

ParkingListController *parklc = [[ParkingListController alloc] autorelease];
[[self navigationController] pushViewController:parklc animated:YES];

我看到“是的,我们应该!”在新视图加载时记录一次,但在设备实际旋转时不会触发。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    NSLog(@"Yes, we should!");
    return YES;
}

我没有任何初始化覆盖,并且 info.plist 列出了所有四个方向。

我错过了什么?谢谢!

编辑 2011-07-07:

奇怪的是,当您从表格视图中选择一个项目时,地图视图会自动旋转!为什么它来自的table view不能旋转?

【问题讨论】:

  • 快速提问:这个 rootViewController 是否在标签栏中使用?如果是这样,您是否对标签栏进行了子类化并在 shouldautorotate 中返回 YES?
  • @bart:你找到解决方案了吗?我也有类似的问题。

标签: iphone ios ipad uiviewcontroller


【解决方案1】:

您正在使用 UINavigationController,它应该返回 true 以进行旋转。请扩展 UINavigationController 并使用 Interface builder 中的扩展类。

#import <Foundation/Foundation.h>
@interface IRUINavigationController : UINavigationController {
}
@end

#import "IRUINavigationController.h"
@implementation IRUINavigationController
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [self.visibleViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
} 
@end

我用过很多项目,而且效果很好。

【讨论】:

  • 我已经尝试过了,它在 iOS 5.1 中运行良好,在 iOS 4.2 中无法正常运行 :)
【解决方案2】:

您是否确保 ParkingListController 的 shouldAutorotateToInterfaceOrientation 也返回 YES?

【讨论】:

  • 它在第一次加载时返回一次 YES,但不会再次触发。即使我旋转设备。
【解决方案3】:

我建议两件事:

  1. 确保你所有的UIViewControllers'shouldAutorotateToInterfaceOrientation都返回YES;

  2. 将日志消息放入willRotateToInterfaceOrientation 以验证视图是否对设备旋转作出反应; shouldAutorotateToInterfaceOrientation 是一种可以被框架以不可预知的方式调用的方法(即,它并不总是在自动旋转时调用)。

除此之外,它应该可以工作。

【讨论】:

  • UIViewControllers 都返回YES。他们不回复willRotateToInterfaceOrientation,他们只回复一次shouldAutorotateToInterfaceOrientation
【解决方案4】:

推送到导航控制器堆栈的每个视图控制器都必须支持相同的方向。这意味着不可能有一些视图控制器只支持纵向而其他只支持横向。换句话说,同一个导航控制器堆栈上的所有视图控制器都应该在委托中返回相同的结果:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

但是有一个简单的解决方案!这是从纵向到横向的示例。这是执行此操作的步骤,下面是支持它的代码。

  1. 创建一个“假”视图控制器,该控制器将作为子导航控制器的根。此视图控制器应支持横向。
  2. 创建 UINavigationController 的新实例,将“假”视图控制器的实例添加为 root,并将横向视图控制器的实例添加为第二个视图控制器
  3. 从父视图控制器将 UINavigationController 实例显示为模态

首先,使用以下代码创建一个新的视图控制器(FakeRootViewController):

@interface FakeRootViewController : UIViewController
@property (strong, nonatomic) UINavigationController* parentNavigationController;
@end

@implementation FaceRootViewController
@synthesize parentNavigationController;
// viewWillAppear is called when we touch the back button on the navigation bar
(void)viewWillAppear:(BOOL)animated {
  // Remove our self from modal view though the parent view controller
  [parentNavigationController dismissModalViewControllerAnimated:YES];
}
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation));
} 

这里是呈现您希望在横向模式下显示的视图控制器的代码:

FakeRootViewController* fakeRootViewController = [[FakeRootViewController alloc] init];[fakeRootViewController.navigationItem setBackBarButtonItem:backButton]; // Set back button
// The parent navigation controller is the one containing the view controllers in portrait mode.
fakeRootViewController.parentNavigationController = parentNavigationController;

UINavigationController* subNavigationController = // Initialize this the same way you have initialized your parent navigation controller.

UIViewController* landscapeViewController = // Initialize the landscape view controller

[subNavigationController setViewControllers:
   [NSArray arrayWithObjects:fakeRootViewController, 
                                               landscapeViewController, nil] animated:NO];

[_navigationController presentModalViewController:subNavigationController animated:YES];

记住,landscapeViewController 也应该有这个实现:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation));
} 

【讨论】:

  • 当我在 LandscapeViewController 中按下返回按钮时,出现错误。我该如何解决这个问题?
  • 这是我的代码://父导航控制器是包含纵向模式视图控制器的导航控制器。 fakeRootViewController.parentNavigationController = self.navigationController; // 以与初始化父导航控制器相同的方式初始化它。 UINavigationController* subNavigationController = [[UINavigationController alloc] init];
猜你喜欢
  • 2010-11-01
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
相关资源
最近更新 更多