我正在使用情节提要容器视图。所以我有一个包含容器视图的视图控制器。我在情节提要中有第二个较小的视图,它通过嵌入转场嵌入到该容器中。到现在为止还挺好。
现在我希望能够在用户点击按钮时动态切换该容器视图的内容。该按钮将位于较大的主视图上。我制作了另一个尺寸相同的视图控制器,并为其赋予了不同的故事板 ID。
但是,我无法弄清楚如何对开关进行编码。我只能为该容器创建一个嵌入 segue。
感激地收到任何帮助。
我正在使用情节提要容器视图。所以我有一个包含容器视图的视图控制器。我在情节提要中有第二个较小的视图,它通过嵌入转场嵌入到该容器中。到现在为止还挺好。
现在我希望能够在用户点击按钮时动态切换该容器视图的内容。该按钮将位于较大的主视图上。我制作了另一个尺寸相同的视图控制器,并为其赋予了不同的故事板 ID。
但是,我无法弄清楚如何对开关进行编码。我只能为该容器创建一个嵌入 segue。
感激地收到任何帮助。
您需要使用自定义容器视图控制器 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];
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
})
}
如果您处理超过 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])
}
}
}