17

我有一個iPhone應用程序,我正在更新到有旋轉問題的iOS 6。我有一個UITabBarController與16 UINavigationCotrollers。大多數子視圖可以在縱向或橫向上工作,但其中一些僅爲縱向。對於iOS 6,事情在不應該時會旋轉。iOS 6 UITabBarController支持當前UINavigation控制器的方向

我試着子類的tabBarController返回當前navigationController的選擇的viewController的supportedInterfaceOrienations

- (NSUInteger)supportedInterfaceOrientations{ 

    UINavigationController *navController = (UINavigationController *)self.selectedViewController; 
    return [navController.visibleViewController supportedInterfaceOrientations]; 
} 

這讓我更接近。視圖控制器在可見時不會旋轉到位,但如果我處於橫向和切換選項卡中,即使不支持,新選項卡也將處於橫向。

理想情況下,應用只會在當前可見視圖控制器支持的方向上。有任何想法嗎?

回答

58

子類的UITabBarController重寫這些方法:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // You do not need this method if you are not supporting earlier iOS Versions 
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

子類的UINavigationController重寫這些方法:

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

然後實現這些方法在你viewControllers,你不想旋轉:

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

-(BOOL)shouldAutorotate 
{ 
    return NO; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

並且對於你想旋轉viewControllers:

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

    -(NSUInteger)supportedInterfaceOrientations 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    -(BOOL)shouldAutorotate 
    { 
     return YES; 
    } 

你tabbarController應該作爲應用程序窗口的RootViewController的。如果你打算支持默認的方向,iPhone的默認設置都是默認的,那麼你不需要做任何其他的事情。如果你想支持顛倒或者你不想支持另一個方向,那麼你需要在應用代理和/或info.plist中設置適當的值。

+7

這幾乎爲我工作。問題是如果我已經在風景中,當我將標籤切換到肖像時,它仍然處於風景中。旋轉的肖像修復它,它不會旋轉回風景,但我仍然需要在第一次加載時使用肖像。 – Ryan

+0

我不確定你需要做什麼來旋轉它,但我敢打賭你會在 - (void)viewWillLayoutSubviews中做到這一點。從內存中我可能不完全正確的方法名稱。我自己的看法,我使用這個代碼的地方,在旋轉時會完全改變,我使用該方法將它們重新配置回肖像模式。你也可以在-viewWillDisappear中嘗試一些東西。也許[self.view setNeedsDisplay]。我目前不在Xcode,所以這些只是我想要探討的想法。 –

+0

不錯!奇蹟般有效!幾乎我所需要的幾乎是 – Dennso

5

我有問題,導航堆棧中的一些視圖控制器支持所有的方向,一些只有肖像,但UINavigationController返回所有應用程序支持的方向,這個小黑客幫了我。我不知道如果這是預期的行爲或者什麼

@implementation UINavigationController (iOS6OrientationFix) 

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

@end 
+0

我不理解這種攻擊是如何幫助你在一個導航控制器的不同視圖控制器上實現不同的行爲的,因爲我知道這個攻擊只會執行一次,所以所有的view controllerd都會具有和topViewController相同的旋轉行爲。興? –

+1

此代碼在每次設備更改方向時都會執行,因此這將返回支持的方向,而此時uiviewcontroller目前處於活動狀態並且可以在此時顯示 – Mindaugas

+0

這很有效。謝謝 –

3

我認爲是更好的類似的東西(如一個類中的方法)

-(NSUInteger) supportedInterfaceOrientations { 
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)]) 
    { 
     return [self.topViewController supportedInterfaceOrientations]; 
    } 
    return UIInterfaceOrientationMaskPortrait; 
} 

這保證了該方法的實現。如果你沒有做這個檢查,並且該方法沒有實現(就像在iOS5環境中),應用程序應該崩潰!

0

如果您打算啓用或禁用所有視圖控制器的旋轉,則不需要子類UINavigationController。 而是使用:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

AppDelegate

如果您計劃,以支持父視圖控制器應用中的所有方向,但不同的方向(UINavigationController棧爲例),你應該結合使用

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

AppDelegate在你的父視圖控制器下面的方法。

- (BOOL)shouldAutorotate 

- (NSUInteger)supportedInterfaceOrientations 

但是,如果你打算在同一個導航堆棧中不同的孩子ViewControllers不同的方向設置(比如我),你需要檢查當前的ViewController導航堆棧。

我創建了一個我UINavigationController子類中的以下內容:

- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    int interfaceOrientation = 0; 

    if (self.viewControllers.count > 0) 
    { 
     DLog(@"%@", self.viewControllers); 
     for (id viewController in self.viewControllers) 
     { 
      if ([viewController isKindOfClass:([InitialUseViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else if ([viewController isKindOfClass:([MainViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown; 
      } 
     } 
    } 
    return interfaceOrientation; 
} 

因爲你不能從孩子ViewControllers你必須以某種方式攔截什麼視圖控制器是目前在導航堆棧呈現視圖控制器的旋轉設置了控制。所以這就是我所做的:)。希望有所幫助!

相關問題