2012-12-11 65 views
0

我創建了兩個相同的故事板,除了一個包含縱向視圖,另一個包含橫向視圖。Xcode 4.5和iOS 6.x中的故事板方向支持?

我不想使用自動調整大小的遮罩,因爲一些視圖的佈局在縱向和橫向之間完全改變。我手動移動視圖控件上的代碼在過去,但我是一個更簡單的方法在此時間後:)

我發現的最接近的解決方案是從「benyboariu」 - Storyboards orientation support for xCode 4.2?

下面的代碼我使用的是在iOS 5.x上正常工作,但不在iOS 6.x上正常工作。

- (void)updateLandscapeView 
{ 
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; 

if (deviceOrientation == UIDeviceOrientationUnknown) 
{ 
    if ([[UIScreen mainScreen] bounds].size.height > [[UIScreen mainScreen] bounds].size.width) 
    { 
     deviceOrientation = UIDeviceOrientationPortrait; 
     self.appDelegate.isShowingLandscapeView = NO; 
    } 
    else 
    { 
     deviceOrientation = UIDeviceOrientationLandscapeLeft; 
     self.appDelegate.isShowingLandscapeView = YES; 
    } 
} 

if (UIDeviceOrientationIsLandscape(deviceOrientation) && !self.appDelegate.isShowingLandscapeView) 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard-Landscape" bundle:[NSBundle mainBundle]]; 
    UIViewController * landscape = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController-Landscape"]; 
    self.appDelegate.isShowingLandscapeView = YES; 
    [UIView transitionWithView:landscape.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{ 
     self.view = landscape.view; 
    } completion:NULL]; 
} 
else if (UIDeviceOrientationIsPortrait(deviceOrientation) && self.appDelegate.isShowingLandscapeView) 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard-Portrait" bundle:[NSBundle mainBundle]]; 
    UIViewController * portrait = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController"]; 
    self.appDelegate.isShowingLandscapeView = NO; 
    [UIView transitionWithView:portrait.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{ 
     self.view = portrait.view; 
    } completion:NULL]; 
} 
} 

在iOS 6.x的調試時,我得到的錯誤是:

終止應用程序由於未捕獲的異常「UIViewControllerHierarchyInconsistency」,理由是:「視圖只能與最多關聯一次一個視圖控制器!查看UIView:0x108276b0; frame =(0 0; 568 268); autoresize = RM + BM;動畫= {position = CABasicAnimation:0x10815c60; bounds = CABasicAnimation:0x1082a5e0; }; layer = CALayer:0x10827710與RootViewController:0x10821f10相關聯。在將此視圖與RootViewController關聯之前清除此關聯:0x961a150。

我通常將視圖控制器與NIB斷開,以解決這種錯誤,但無法通過故事板進行拼接。

任何人有任何想法?

回答

0

那麼,嘗試各種方法來嘗試和解決這個問題後,我想出了這個解決方案,它適用於iOS 5.x和6.x.

基本上,這個問題似乎是因爲導航控制器,這樣,而不是做

self.view = landscape.view; 

self.view = portrait.view; 

需要更換所有包含在導航控制器的視圖控制器疊加。

我在下面的代碼中做的是在導航控制器堆棧中創建所有視圖控制器的NSMutableArray。然後循環每個視圖控制器並獲取視圖標記以確定哪個視圖需要替換。然後,我簡單地使用橫向或縱向版本替換視圖控制器,然後將導航控制器視圖控制器陣列設置爲修改後的陣列,從而替換所有視圖控制器。

if (UIDeviceOrientationIsLandscape(deviceOrientation) && !self.appDelegate.isShowingLandscapeView) 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard-Landscape" bundle:[NSBundle mainBundle]]; 
    SearchViewController * landscape = [storyboard instantiateViewControllerWithIdentifier:@"SearchViewController-Landscape"]; 
    self.appDelegate.isShowingLandscapeView = YES; 
    [UIView transitionWithView:landscape.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{ 
     NSMutableArray * viewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]]; 
     if (viewControllers && [viewControllers count] > 0) 
     { 
      for (NSUInteger index = 0; index < [viewControllers count]; index++) 
      { 
       if ([[[viewControllers objectAtIndex:index] view] tag] == 1000) 
       { 
        RootViewController * root = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController-Landscape"]; 
        [viewControllers replaceObjectAtIndex:index withObject:root]; 
       } 
       else if ([[[viewControllers objectAtIndex:index] view] tag] == 2000) 
       { 
        [viewControllers replaceObjectAtIndex:index withObject:landscape]; 
       } 
      } 

      [self.navigationController setViewControllers:viewControllers]; 
     } 
    } completion:NULL]; 
} 
else if (UIDeviceOrientationIsPortrait(deviceOrientation) && self.appDelegate.isShowingLandscapeView) 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard-Portrait" bundle:[NSBundle mainBundle]]; 
    SearchViewController * portrait = [storyboard instantiateViewControllerWithIdentifier:@"SearchViewController"]; 
    self.appDelegate.isShowingLandscapeView = NO; 
    [UIView transitionWithView:portrait.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{ 
     NSMutableArray * viewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]]; 
     if (viewControllers && [viewControllers count] > 0) 
     { 
      for (NSUInteger index = 0; index < [viewControllers count]; index++) 
      { 
       if ([[[viewControllers objectAtIndex:index] view] tag] == 1000) 
       { 
        RootViewController * root = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController"]; 
        [viewControllers replaceObjectAtIndex:index withObject:root]; 
       } 
       else if ([[[viewControllers objectAtIndex:index] view] tag] == 2000) 
       { 
        [viewControllers replaceObjectAtIndex:index withObject:portrait]; 
       } 
      } 

      [self.navigationController setViewControllers:viewControllers]; 
     } 
    } completion:NULL]; 
} 

我已經擴展了代碼以展示如何在導航控制器中使用嵌套視圖。如果你正在使用根視圖控制器,那麼顯然不需要遍歷所有視圖控制器,只需替換索引爲0的視圖控制器。

希望這可以幫助某人!

+0

嗨,你對1000和2000是什麼? – Jules

0

將您的portait視圖控制器更改爲普通視圖(將其從視圖控制器中取出)。現在你應該能夠將它實例化爲一個UIView,並進行轉換,而不必擔心它與多個視圖控制器相關聯。

+0

我已經嘗試從故事板中的控制器中刪除UIView,但它看起來像你只能有控制器在那裏,即你需要一個UIViewController不是一個UIView,或一個UITableViewController不是一個UITableView等。 –