13

我有一个导航控制器有几个视图控制器。我需要支持所有视图控制器的所有方向,除了一个仅支持横向的特殊视图控制器。这个特殊的视图控制器出现在导航堆栈的中间。我做了很多研究,但找不到任何好的解决方案。以下是我阅读和尝试的链接。支持在UINavigationController中只有一个视图的横向

http://www.iphonedevsdk.com/forum/iphone-sdk-development/3219-force-landscape-mode-one-view.html#post60435

How to rotate screen to landscape?

How to autorotate from portrait to landscape mode? iPhone - allow landscape orientation on just one viewcontroller http://goodliffe.blogspot.com/2009/12/iphone-forcing-uiview-to-reorientate.html

接下来我要尝试,以显示特殊视图控制器presentModalViewController更换导航控制器。然后,我将在特殊视图控制器内部创建一个新的导航视图控制器来推送后续的视图控制器。

如果有人有更好的主意,请让我知道。非常感谢!

UPDATE:我已经成功地使用我上述方法:替换与pushViewControllerpresentModalViewController并创建一个新的导航控制器。

+0

你能分享样本代码吗? – 2012-12-12 06:20:39

回答

8

每个视图控制器后推新控制器。这意味着不可能让某些视图控制器仅支持肖像,而其他视图控制器仅支持肖像。换句话说,相同的导航控制器堆栈上的所有视图控制器应返回相同的委托:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

但有一个简单的解决这个!这是一个从纵向到横向的例子。下面是执行它的步骤,下面是代码来支持它。

  1. 创建一个'假'视图控制器,它将作为子导航控制器中的根。这个视图控制器应该支持风景。
  2. 创建UINavigationController的新实例,添加“假”的视图控制器作为根的实例和横向视图控制器作为第二视图控制器
  3. 目前UINavigationController实例为从父视图控制器
  4. 模式的一个实例

首先,创建一个新的视图控制器(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)); 
} 
0

应该是简单的实现

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
每个 UIViewController

推入你的UINavigationController。在一个UIViewController的视图不应该旋转的情况下,该特定方向的return NO即为该特定的UIViewController。 有一个疑难杂症虽然这里,如果你的UINavigationController实现

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

它会阻止其从viewControllers接收方法。在这种情况下,你应该使用

[[self topViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
+3

我希望这很简单。你尝试过吗?这有几个问题。 1.如果在手机为纵向时呈现特殊横向视图,则当您将手机转为横向时,视图会意外旋转至纵向。 2.当您第一次渲染特殊横向视图时,然后将手机旋转至纵向,然后退出特殊视图并重新进入,视图会意外旋转。这似乎是导航控制器的一个问题,我真的希望Apple能够使它适用于您所描述的内容。 – 2011-02-17 08:26:37

+0

我试过了。我认为您遇到的问题可能会针对您的应用程序。尝试启动一个新项目来隔离UINavigationController旋转问题,然后运行一些实验。 – schellsan 2011-02-17 18:47:43

0

将消息转发给topViewController你可以试试这个代码在你UINavigationController调用当前可见视图的shouldAutorotateToInterfaceOrientation。在我的情况下,我有UINavigationControllerUITabBarController,但你可能可以适应其他情况。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if ([appDelegate.tabBarController.selectedViewController respondsToSelector:@selector(topViewController)]) 
    { 
     UINavigationController *nc = (UINavigationController*)appDelegate.tabBarController.selectedViewController; 
     return [nc.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
    } 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 
0

你可以让动作: 改变你的代码按照schellsan的建议,下一个 - 尝试添加currentViewController(这将推动导航的viewController)作为财产的appDelegate。当您尝试推送视图控制器时,请在此之前将其设置为当前视图控制器。接下来 - 在导航控制器中创建rootViewController的子类。在这一小类owerload方法

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    // Overriden to allow any orientation. 
    return [appDelegate.currentViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

它应该工作,如果你不使用导航栏和弹出推到导航控制器栈必须支持同一方位的老

+3

你如何在iOS 6版本中实现同样的功能.. – Krishnan 2012-10-17 07:20:43

1

有一个私有API给力的方向变化。把你推视图控制器的-viewWillAppear:

if ([UIDevice instancesRespondToSelector:@selector(setOrientation:)]) { 
    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 
} 

为了抑制编译器警告,添加到您的视图控制器的.m文件:

@interface UIDevice() 
- (void)setOrientation:(UIDeviceOrientation)orientation; // private API to let POIEntryVC be pushed over landscape route view 
@end 

像往常一样,有被拒绝的危险和在使用私有API时未来操作系统版本可能会崩溃。请自担风险!

一般来说,在大多数情况下,呈现模态视图控制器是更好的解决方案。

相关问题