简体   繁体   中英

How to show a segue inside a child view controller?

I have a main view controller, inside this view controller I show another view controller as its child view controller. The code to show the child view controller as shown below. The self.currentController is the child controller which will be located inside the main controller.

        self.addChildViewController(self.currentController!)
        self.currentController?.view.frame = self.operationView.bounds
        self.currentController?.view.layoutIfNeeded()
        self.operationView.addSubview((self.currentController?.view!)!)
        self.setNeedsStatusBarAppearanceUpdate()

Now I want to perform a show segue (another controller, let call it ThirdController) inside the child view controller by using below code:

performSegueWithIdentifier("ShowSegue", sender: nil)

on doing this, the ThirdController will fill on the full screen. What I want to do is to show the third controller on the child controller place. How can I do this?

OK, Sorry I don't know how to write the answer in Swift. So I'll just show you how my solution is done in Objective-C.

Code to load the first subview:

- (void)loadASubview
{
    subview = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstView"];

    [self addChildViewController:subview];
    [self.view addSubview:subview.view];

    [subview didMoveToParentViewController:self];
    [subview.view setFrame:self.view.bounds];
}

Code to unload the subview:

- (void)unloadASubview
{
    [subview willMoveToParentViewController:nil];
    [subview.view removeFromSuperview];
    [subview removeFromParentViewController];
}

Initially, when I need to load subview A, I will simply call loadASubview . After that, if I need to load another subview, I will unload the subview I previously loaded by calling unloadASubview before loading the new subview.

Please take note that the "subview" variable inside the functions are declared outside.

I hope this will help you.

Swift 4

func loadASubView(){
    subview = self.storyboard?.instantiateViewController(withIdentifier: "childviewstoryboardid")
    self.addChildViewController(subview!)

    self.containerView.addSubview(subview!.view)
    subview?.didMove(toParentViewController: self)
    subview?.view.frame = self.containerView.frame

}

func unloadASubview(){
    subview?.willMove(toParentViewController: nil)
    subview?.view.removeFromSuperview()
    subview?.removeFromParentViewController()

}

That's my resolve with autoLayout. It is a best way to do it without any extra modify.

In the Children View Controller , you can normally use this function "show(vc: UIViewController, sender: Any?)" to show a viewController(if have navigationController, it will push a new Controller, nor present it)

Swift 4.2

func setChild() {
    let vc = UIStoryboard(name: "YOUR_STORYBOARD_NAME", bundle: nil).instantiateViewController(withIdentifier: "YOUR_CHILD_ID")
    self.addChild(vc)
    // need to set translatesAutoresizingMaskIntoConstraints false to enable auto layout
    vc.view.translatesAutoresizingMaskIntoConstraints = false
    /// add subview to parent
    view.addSubview(vc.view)
    /// send subview to back for show other view in parent
    view.sendSubviewToBack(vc.view)
    /// call did move to parent to show current children
    vc.didMove(toParent: self)

    /// <---create auto layout with VFL--->
    let horiConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|",
                                                        options: .alignAllCenterY,
                                                        metrics: nil,
                                                        views: ["view" : vc.view])
    let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|",
                                                        options: .alignAllCenterX,
                                                        metrics: nil,
                                                        views: ["view" : vc.view])
    view.addConstraints(horiConstraints)
    view.addConstraints(verticalConstraints)
    view.layoutIfNeeded()
}

After that u can remove the first child

func removeFirstChild() {
    children.first?.willMove(toParent: nil)
    children.first?.view.removeFromSuperview()
    children.first?.didMove(toParent: nil)
}

Or remove all child from parent

func removeAllChild() {
    for child in children {
        child.willMove(toParent: nil)
        child.view.removeFromSuperview()
        child.didMove(toParent: nil)
    }
}

Object-C

- (void)setChild {
    UIViewController *vc = [[UIStoryboard storyboardWithName:@"YOUR_STORYBOARD_NAME" bundle:nil] instantiateViewControllerWithIdentifier:@"YOUR_CHILD_ID"];
    [self addChildViewController:vc];
    // need to set translatesAutoresizingMaskIntoConstraints false to enable auto layout
    vc.view.translatesAutoresizingMaskIntoConstraints = NO;
    /// add subview to parent
    [self.view addSubview:vc.view];
    /// send subview to back for show other view in parent
    [self.view sendSubviewToBack:vc.view];
    /// call did move to parent to show current children
    [vc didMoveToParentViewController:self];


    /// <---create auto layout with VFL--->
    NSArray<__kindof NSLayoutConstraint *> *horiConstraints;
    horiConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[view]-0-|"options:NSLayoutAttributeCenterY
                                                          metrics:nil
                                                            views:@{@"view": vc.view}];
    NSArray<__kindof NSLayoutConstraint *> *verticalConstraints;
    verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]-0-|"
                                                              options:NSLayoutAttributeCenterX
                                                              metrics:nil
                                                                views:@{@"view": vc.view}];
    [self.view addConstraints:horiConstraints];
    [self.view addConstraints:verticalConstraints];
    [self.view layoutIfNeeded];
}

After that u can remove the first child

- (void)removeFirstChild {
    UIViewController *child = self.childViewControllers.firstObject;
    [child willMoveToParentViewController:nil];
    [child.view removeFromSuperview];
    [child didMoveToParentViewController:nil];
}

Or remove all child from parent

- (void)removeAllChild {
    for (UIViewController* child in self.childViewControllers) {
        [child willMoveToParentViewController:nil];
        [child.view removeFromSuperview];
        [child didMoveToParentViewController:nil];
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM