Динамический просмотр контейнера
Я использую представление контейнера раскадровки. Поэтому у меня есть контроллер вида, содержащий контейнерный вид. У меня есть второй, меньший вид в раскадровке, который встроен в этот контейнер через встроенный segue. Пока все хорошо.
Теперь я хотел бы динамически переключаться с содержимым этого вида контейнера, когда пользователь нажимает кнопку. Кнопка будет на основном, большем, представлении. Я сделал другой контроллер представления того же меньшего размера и дал ему другой идентификатор раскадровки.
Однако я не могу понять, как закодировать коммутатор. Я могу создать только один встроенный segue для этого контейнера.
Любая помощь с благодарностью получила.
Ответы
Ответ 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])
}
}
}