如何以编程方式选择嵌入式视图的控制器?

时间:2016-04-17 02:01:27

标签: ios swift

我在视图控制器上有一个嵌入式容器,我想根据具体情况更改它的内容。我应该怎么做,知道只有一个嵌入segue链接到嵌入式容器。

我尝试在我的嵌入式容器和我的2个可能的内容视图之间放置一个视图控制器,但由于自定义segues它不会工作(错误:"无法创建带有类&#39的segue) ;空&#39)。如果有人可以告诉我更多相关信息,我就不会理解这个错误:)

我通过创建选项卡视图,以编程方式在标签之间切换,或通过添加2个容器视图并隐藏不需要的视图来阅读有关解决此问题的一些方法,但这些看起来有点像hacky。

这样做的最佳做法是什么? (请快点)

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

有两种方法可以做到这一点,第一种方法是在彼此的顶部添加两个容器视图,并将alpha设置为0表示一个,1表示另一个,并在想要在视图控制器之间切换时切换alpha值。 这样做的缺点是总会有两个视图控制器被实例化。 第二种方法是将segue的类型从embed更改为自定义segue(这将允许您在storyboard中添加多个segue)来加载或交换视图控制器。以下是我实现的segue的实现,如果你能理解它,你可以在swift中实现它。

 (void)perform
//
// Used to seque between the master view controller and its immediate child view controllers and also from the homw view controller
// and all its immediate child controllers.
// At app launch then it is necessary to directly load a particular view controller - this is determined by checking that the source
// view controller has no children. At other times the seque is used to switch from one controller to another.
//
{

    //
    // This seque is for use when there is a container view controller where it is necessary to switch the contained view controllers (storyboards only permit one embed seque).
    //
    //
    //                             embed segue                              segueA
    //             MainVC  --------------------------> ContainerVC -------------------> VCA
    //     (has the view containing
    //       the containded VC)
    //                                                                      sequeB
    //                                                             --------------------> VCB
    //
    //
    // When the app initially launches the OS will automatically execute the embed seque and thus the ContainerVC gets the opportunity in its viewDidLoad to decide which
    // VC to load at that point and then execute either segueA or sequeB. Assuming it calls sequeA then when the seque executes the source will be the ContainerVC and the
    // destination with will VCA. The seque checks to see if the containerVC already has any children, if not then it knows to just add VCA as a child.
    //

    DDLogInfo(@"SEGUE - entered seque");
    UIViewController *container = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;
    if([container.childViewControllers count] == 0)
    {
        DDLogInfo(@"SEGUE - adding intitial VC: %@", [destination description]);
        // The containerVC doesn't yet any any children so just add the destination VC as a child
        [container addChildViewController:destination];
        destination.view.frame = container.view.frame;
        [container.view addSubview:destination.view];
        [destination didMoveToParentViewController:container];
    }
    else
    {
        // The containerVC already has an existing child and thus it is necessary to swap it out and replace it with the new child
        UIViewController* currentChild = container.childViewControllers[0];

        currentChild.view.userInteractionEnabled = NO;
        PyngmeAssert([container.childViewControllers count] == 1, @"More than one child controller");

        // First check to make sure the destination type is not the same as the current child
        if([destination isMemberOfClass: [currentChild class]])
        {
            DDLogInfo(@"SEGUE: Trying to swap view controllers of the same type *****");
        }
        else
        {
            // Swap the new VC for the old VC
            destination.view.frame = container.view.frame;
            [currentChild willMoveToParentViewController:nil];
            [container addChildViewController:destination];

            [container transitionFromViewController:currentChild
                                   toViewController:destination
                                           duration:0.35
                                            options:UIViewAnimationOptionTransitionCrossDissolve
                                         animations:^{
                                         }
                                         completion:^(BOOL finished) {
                                             [currentChild removeFromParentViewController];
                                             [destination didMoveToParentViewController:container];
                                             DDLogInfo(@"SEGUE finished swapping seque");
                                         }];
        }
    }
}