簡體   English   中英

處理具有兩種不同視圖的視圖控制器的最佳方法:縱向和橫向

[英]The best way to handle a view controller with two different views: portrait and landscape

這個想法是根據設備的方向來處理兩個不同的視圖。

基本上,如果我們排除視圖,則控制器本身只是一段代碼。 它能夠處理兩個視圖中的任何一個,或者是因為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;
}

根據Apple的說法,如果兩者之間存在明顯差異,則最好的做法是針對兩個方向使用兩個單獨的視圖控制器。 他們說

如果要基於設備是縱向還是橫向顯示不同的相同數據,則可以使用兩個單獨的視圖控制器。 一個視圖控制器應以主要方向(通常為縱向)管理數據的顯示,而另一個視圖控制器則以替代方向管理數據的顯示。 與每次方向更改時對視圖層次結構進行重大更改相比,使用兩個視圖控制器更加簡單高效。 它允許每個視圖控制器集中精力於一種方向的數據表示,並相應地管理事物。 這也消除了需要對當前方向進行條件檢查來填充視圖控制器代碼的麻煩。

到現在為止還挺好。

就我而言,我認為簡單是最好的解決方案。 然后,我放棄了兩個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];

                    }
     ];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM