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時未來操作系統版本可能會崩潰。請自擔風險!

一般來說,在大多數情況下,呈現模態視圖控制器是更好的解決方案。

相關問題