Switch container view dynamically

前端 未结 3 661
说谎
说谎 2020-12-08 15:21

I\'m using a storyboard container view. So I have a view controller containing a container view. I have a second, smaller view in the storyboard, which is embedded in that c

相关标签:
3条回答
  • 2020-12-08 15:49

    rdelmar's answer converted to Swift syntax

        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.initialVC = self.childViewControllers.last
            self.substituteVC = self.storyboard!.instantiateViewControllerWithIdentifier("Substitute")
            self.currentVC = self.initialVC;
    
    }
        @IBAction func switchControllers(sender: UISegmentedControl) {
            switch sender.selectedSegmentIndex{
                case 0:
                    if (self.currentVC == self.substituteVC) {
                        self.addChildViewController(self.initialVC)
                        //self.initialVC.view.frame = self.containerView.bounds
                        moveToNewController(self.initialVC)
                    }
                case 1:
                    if (self.currentVC == self.initialVC) {
                        self.addChildViewController(self.substituteVC)
                        //self.substituteVC.view.frame = self.containerView.bounds
                        moveToNewController(self.substituteVC)
                    }
                default:
                break;
            }
        }
    
        func moveToNewController(newController : UIViewController){
            self.currentVC.willMoveToParentViewController(nil)
            self.transitionFromViewController(
                self.currentVC!,
                toViewController: newController,
                duration: 0.2,
                options: UIViewAnimationOptions.TransitionCrossDissolve,
                animations: nil,
                completion: { finished in
                    self.currentVC.removeFromParentViewController()
                    newController.didMoveToParentViewController(self)
                    self.currentVC = newController
            })
    
        }
    
    0 讨论(0)
  • 2020-12-08 15:51

    You need to use the custom container view controller api to do the switching of the controllers. The following code shows one way to do that. In this project I had a segmented control in the main view controller (the one with the container view) that switches beetween the two controllers. initialVC is the controller that's embedded in IB, and substituteVC is the one I'm switching to. The property, container, is an IBOutlet to the container view.

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.initialVC = self.childViewControllers.lastObject;
        self.substituteVC = [self.storyboard instantiateViewControllerWithIdentifier:@"Substitute"];
        self.currentVC = self.initialVC;
    }
    
    -(IBAction)switchControllers:(UISegmentedControl *)sender {
    
        switch (sender.selectedSegmentIndex) {
            case 0:
                if (self.currentVC == self.substituteVC) {
                    [self addChildViewController:self.initialVC];
                    self.initialVC.view.frame = self.container.bounds;
                    [self moveToNewController:self.initialVC];
                }
                break;
            case 1:
                if (self.currentVC == self.initialVC) {
                    [self addChildViewController:self.substituteVC];
                    self.substituteVC.view.frame = self.container.bounds;
                    [self moveToNewController:self.substituteVC];
                }
                break;
            default:
                break;
        }
    }
    
    
    -(void)moveToNewController:(UIViewController *) newController {
        [self.currentVC willMoveToParentViewController:nil];
        [self transitionFromViewController:self.currentVC toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionFlipFromLeft animations:nil
                                completion:^(BOOL finished) {
                                    [self.currentVC removeFromParentViewController];
                                    [newController didMoveToParentViewController:self];
                                    self.currentVC = newController;
                                }];
    }
    

    After Edit:

    If you want to go to the new controller with no animation, you can do it like this (this substitutes for the code that I had under case 1).

    [self addChildViewController:self.substituteVC];
    [self.substituteVC didMoveToParentViewController:self];
    self.substituteVC.view.frame = self.container.bounds;
    [self.container addSubview:self.substituteVC.view];
    [self.currentVC removeFromParentViewController];
    
    0 讨论(0)
  • 2020-12-08 16:01

    If you deal with more than 2 child view controllers it's a good idea to store them in array. Also, you'll need to apply constraints every time you add a new subview to the container view. Here's a modified version of the accepted answer (using Swift 2 syntax):

    import UIKit
    
    class FooBarViewController: UIViewController
    {
        // MARK: - IBOutlets
    
        @IBOutlet weak var containerView: UIView!
    
        // MARK: - Properties
    
        var vcs = [UIViewController]()
        var currentVC: UIViewController!
    
        // MARK: - ViewController Lifecycle
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
    
            vcs.append(childViewControllers.last!)
            vcs.append(storyboard!.instantiateViewControllerWithIdentifier("FooViewControler"))       
            vcs.append(storyboard!.instantiateViewControllerWithIdentifier("BarViewController"))
            currentVC = vcs[0]
    
            for vc in vcs {
                vc.view.frame = containerView.bounds
            }
        }
    
        // MARK: - Methods
    
        func switchToViewController(targetVC: UIViewController)
        {
            addChildViewController(targetVC)
            currentVC.willMoveToParentViewController(nil)
    
            transitionFromViewController(
                currentVC,
                toViewController: targetVC,
                duration: 0.0, // 0.3
                options: .TransitionNone, // .TransitionCrossDissolve,
                animations: nil,
                completion: { finished in
                    self.currentVC.removeFromParentViewController()
                    targetVC.didMoveToParentViewController(self)
                    self.currentVC = targetVC
                    self.applyConstraints()
            })
        }
    
        func applyConstraints()
        {
            let viewsDict = ["newSubview": currentVC.view]
    
            currentVC.view.translatesAutoresizingMaskIntoConstraints = false
    
            containerView.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("H:|[newSubview]|",
                    options: NSLayoutFormatOptions(rawValue: 0),
                    metrics: nil,
                    views: viewsDict))
    
            containerView.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|[newSubview]|",
                    options: NSLayoutFormatOptions(rawValue: 0),
                    metrics: nil, views:
                    viewsDict))
        }
    
        // MARK: - IBActions
    
        @IBAction func switchControllers(sender: UISegmentedControl)
        {
            let i = sender.selectedSegmentIndex
    
            if currentVC != vcs[i] {
                self.addChildViewController(vcs[i])
                switchToViewController(vcs[i])
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题