Подтвердить что ты не робот

Динамический просмотр контейнера

Я использую представление контейнера раскадровки. Поэтому у меня есть контроллер вида, содержащий контейнерный вид. У меня есть второй, меньший вид в раскадровке, который встроен в этот контейнер через встроенный segue. Пока все хорошо.

Теперь я хотел бы динамически переключаться с содержимым этого вида контейнера, когда пользователь нажимает кнопку. Кнопка будет на основном, большем, представлении. Я сделал другой контроллер представления того же меньшего размера и дал ему другой идентификатор раскадровки.

Однако я не могу понять, как закодировать коммутатор. Я могу создать только один встроенный segue для этого контейнера.

Любая помощь с благодарностью получила.

4b9b3361

Ответ 1

Для переключения коммутаторов необходимо использовать пользовательский контроллер представления контейнера api. Следующий код показывает один из способов сделать это. В этом проекте у меня был сегментированный элемент управления в главном контроллере представления (тот, который имеет вид контейнера), который переключается между двумя контроллерами. initialVC - это контроллер, встроенный в IB, а substituteVC - тот, к которому я перехожу. Свойство, контейнер, является 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];

Ответ 2

rdelmar answer, преобразованный в синтаксис 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
        })

    }

Ответ 3

Если вы имеете дело с более чем двумя контроллерами дочерних представлений, рекомендуется хранить их в массиве. Кроме того, вам придется применять ограничения каждый раз, когда вы добавляете новое представление в представление контейнера. Здесь измененная версия принятого ответа (с использованием синтаксиса 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])
        }
    }
}