23

我正在使用情节提要容器视图。所以我有一个包含容器视图的视图控制器。我在情节提要中有第二个较小的视图,它通过嵌入转场嵌入到该容器中。到现在为止还挺好。

现在我希望能够在用户点击按钮时动态切换该容器视图的内容。该按钮将位于较大的主视图上。我制作了另一个尺寸相同的视图控制器,并为其赋予了不同的故事板 ID。

但是,我无法弄清楚如何对开关进行编码。我只能为该容器创建一个嵌入 segue。

感激地收到任何帮助。

4

3 回答 3

42

您需要使用自定义容器视图控制器 api 来进行控制器的切换。以下代码显示了一种方法。在这个项目中,我在主视图控制器(带有容器视图的那个)中有一个分段控件,可以在两个控制器之间切换。initialVC 是嵌入在 IB 中的控制器,而替代VC 是我要切换到的控制器。属性 container 是容器视图的 IBOutlet。

- (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;
                            }];
}

编辑后:

如果你想去没有动画的新控制器,你可以这样做(这代替了我在案例 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];
于 2013-04-17T05:13:15.137 回答
4

rdelmar 的答案转换为 Swift 语法

    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
        })

    }
于 2015-09-16T02:30:00.167 回答
0

如果您处理超过 2 个子视图控制器,最好将它们存储在数组中。此外,每次将新子视图添加到容器视图时,都需要应用约束。这是接受答案的修改版本(使用 Swift 2 语法):

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])
        }
    }
}
于 2015-12-16T23:08:25.810 回答