动态切换容器视图

时间:2013-04-17 05:03:51

标签: objective-c

我正在使用故事板容器视图。所以我有一个包含容器视图的视图控制器。我在故事板中有第二个较小的视图,它通过嵌入segue嵌入到该容器中。到目前为止一切都很好。

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

但是,我无法弄清楚如何编码交换机。我只能为该容器创建一个嵌入segue。

感激不尽的任何帮助。

3 个答案:

答案 0 :(得分:40)

您需要使用自定义容器视图控制器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];

答案 1 :(得分:4)

rdelmar's answer转换为Swift语法

public void onItemClick(AdapterView<?> parent, View view, int position, .......

答案 2 :(得分: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])
        }
    }
}