2014-01-30 35 views
0

這個想法是處理兩個不同的視圖,具體取決於設備的方向。處理具有兩種不同視圖的視圖控制器的最佳方式:縱向和橫向

基本上,如果我們排除視圖,控制器本身只是一塊代碼。它能夠處理這兩個視圖中的任何一個 - 或者是因爲IBOutlets在兩個IB故事板視圖控制器中具有相同的名稱,或者因爲它針對設備方向使用了if語句。我嘗試了兩種不同的方式來做到這一點,但我仍然面臨着一個問題:我結束了兩個實際的控制器實例,它們中的每一個都運行相同的代碼(因此兩次線程和其他代碼片段同時運行)。

我想擺脫一個,只有一個實例運行。

你會建議什麼?可能有更好的方式來處理我的用例,不是嗎?

我的代碼如下:

- (void)loadControllers 
{ 
    self.firstController = (DashboardViewController*)[[self storyboard] instantiateViewControllerWithIdentifier:@"DashboardPortrait" ]; 
    self.firstController.isDashboard = NO; 

    self.secondController = (DashboardViewController*)[[self storyboard] instantiateViewControllerWithIdentifier:@"DashboardLandscape"]; 
    self.secondController.isDashboard = YES; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [self loadControllers]; 

    DashboardViewController *viewController = self.firstController; 
    [self addChildViewController:viewController]; 

    viewController.view.frame = self.contentView.bounds; 

    [self.contentView addSubview:viewController.view]; 

    self.currentViewController = viewController; 
} 

- (void)setOrientationPortrait:(BOOL)portrait { 
    DashboardViewController *viewController = portrait?self.firstController:self.secondController; 


    // Make sure the two view controllers share the same parent. 
    [self addChildViewController:viewController]; 

    // If not same parent, dont transition 
    if (viewController.parentViewController!=self.currentViewController.parentViewController) return; 

    [self transitionFromViewController:self.currentViewController 
         toViewController:viewController 
           duration:0.0 
           options:UIViewAnimationOptionTransitionNone 
          animations:^{ 
           [self.currentViewController.view removeFromSuperview]; 
           viewController.view.frame = self.contentView.bounds; 
           [self.contentView addSubview:viewController.view]; 
          } 
          completion:^(BOOL finished) { 
           [viewController didMoveToParentViewController:self]; 
           [self.currentViewController removeFromParentViewController]; 
           self.currentViewController = viewController; 


           // Direct video to the destination, current controller 
           AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 

           [app faceRecognitionAttachPreview:self.currentViewController.previewView]; 
          } 
    ]; 

    self.navigationItem.title = viewController.title; 
} 
+0

可能重複http://stackoverflow.com/questions/15540771/ load-different-xib-files-on-orientation-in-ios) – Marco

回答

0

到目前爲止,這麼好。

在我的情況下,我認爲最簡單的是最好的解決方案。 然後,我放棄了我的兩個vc架構,再加上一個帶有嵌入視圖的vc,轉而使用一個視圖的vc。

問題是您需要編寫代碼來處理UI差異 在我的情況下,我還必須更改vc中視圖的層次結構以便能夠在運行時禁用其中的一些視圖的層次結構。 此外,我不得不放大水平模式的視圖,並使用圖層的縮放轉換。不好的一點是,它實際上是放大圖形級別。文字不像增加字體大小那樣光滑。這是我很快就會做的事情,以保持最佳質量。

我在裝置旋轉選擇器到目前爲止寫的代碼如下:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 

    static CGRect actionViewRect = (CGRect){0,0,0,0}; 

    if (!actionViewRect.size.height) actionViewRect = self.actionView.frame; 

    //self.containerView.hidden = YES; 

    [UIView transitionWithView:self.view 
         duration:0.3f 
         options:UIViewAnimationOptionTransitionCrossDissolve 
        animations:^{ 

         // From portrait to landscape 
         if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) { 
          self.navigationController.navigationBar.hidden = YES; 
          self.tabBarController.tabBar.hidden = YES; 

          self.statusBar.hidden = NO; 
          self.actionView.hidden = YES; 
          self.containerViewTopToSuperView.constant  = self.navigationController.navigationBar.frame.origin.y; 
          self.containerViewBottomToSuperView.constant = 0; 
          CGRect rect = actionViewRect; 
          rect.origin.y = actionViewRect.origin.y+actionViewRect.size.height; 
          rect.size.height = 0; 
          self.actionView.frame = rect; 

          // -- location view (bigger) 
          CGFloat 
          s = 1.5; 
          self.locationView.layer.transform = CATransform3DMakeScale(s, s, 1); 

          // -- HUD view (bigger) 
          s = 1.5; 
          self.hudLeft.layer.transform = CATransform3DMakeScale(s, s, 1); 

         } 
         // From landscape to portrait 
         else { 
          self.navigationController.navigationBar.hidden = NO; 
          self.tabBarController.tabBar.hidden = NO; 

          self.locationView.layer.transform = CATransform3DIdentity; 


          self.actionView.hidden = NO; 
          self.actionView.frame = actionViewRect; 
          self.containerViewTopToSuperView.constant  = self.navigationController.navigationBar.frame.origin.y 
                      + self.navigationController.navigationBar.frame.size.height; 
          self.containerViewBottomToSuperView.constant = self.tabBarController.tabBar.frame.size.height; 

          // -- location view (standard) 
          self.hudLeft.layer.transform = CATransform3DIdentity;      } 

          // -- HUD view (bigger) 
          self.hudLeft.frame   = (CGRect){.origin=(CGPoint){0,0}, .size=self.hudLeft.frame.size}; 
        } 
        completion:^(BOOL finished) { 
         // Direct video to the destination, current controller 
         AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 
         app.previewLayer.orientation = [[UIDevice currentDevice] orientation]; 

         //self.containerView.hidden = NO; 

         //[UIView setAnimationsEnabled:YES]; 

        } 
    ]; 
} 
的[負載不同XIB文件上在IOS方向](
1

Apple,它是有兩個方向的兩個獨立的視圖控制器如果兩者之間的差異顯著的最佳實踐。 They say

如果您希望根據設備是縱向還是橫向來呈現相同的數據,則要這樣做的方法是使用兩個單獨的視圖控制器。一個視圖控制器應該管理主要方向(通常是縱向)中的數據顯示,而另一個視圖控制器管理以替代方向顯示數據。使用兩個視圖控制器比每次方向更改時對視圖層次結構進行重大更改都更簡單,更高效。它允許每個視圖控制器專注於以一個方向呈現數據並相應地管理事物。它還消除了對當前方向進行條件檢查來清理視圖控制器代碼的需要。

+1

我確實同意他們,因此請您與您聯繫。但是,這正是我迄今爲止所做的。關鍵的區別在於你如何進行兩者之間的轉換。在我的第一次嘗試中,我只是卸載了以前的vc。但它引入了我想要擺脫的時間滯後。因此,首先調用loadControllers。但是,我面臨我在問題中提到的問題。你會怎麼做? –

相關問題