从 viewController 中切换 containerView 内容

Switching containerView content from within viewController

我有三个视图控制器 MainA​​BMain ViewController 包含 ContainerView 和其他内容以及 containerView 中的所有事务。 ViewControllerA 按下时有 ButtonA 容器的内容必须更改为 ViewControllerB 我怎样才能做到这一点?我找不到任何类似的例子。

当您从视图 A 中按 Button A 时:

@IBAction func BtnAPress(_ sender: Any)
{
   //Moving Storyboard
   let Storyboard = UIStoryboard(name: "Main", bundle: nil)
   let MainVC : UIViewController = Storyboard.instantiateViewController(withIdentifier: "ViewControllerB")
   self.present(MainVC, animated: true, completion: nil)
}

我用示例创建了一个故事板。您可以从 here.

下载

您需要将嵌入视图更改为导航控制器,然后您可以使用 segue 在按下按钮时显示第二个视图。还 hide/show 导航栏取决于要求。

您需要为此创建委托。 首先创建一个协议

protocol ViewControllerADelagate {
    func didPressOnButtonA()
}

在 ViewControllerA 中添加以下委托变量

class ViewControllerA {
    ....

    var delegate : ViewControllerADelagate?
    ....
}

在 ViewControllerA 中,在按下按钮时添加以下内容

@IBAction buttonAPressed(sender : UIButton) {
    self.delegate?.didPressOnButtonA()
}

在 MainViewController 中将 ViewControllerA 的委托分配给自己 喜欢

vcA.delegate = self

一样在MainViewController中实现委托方法
func didPressOnButtonA {
        let storyboard : UIStoryboard = UIStoryboard(name: storyboard, bundle: nil)
        let vcB : UIViewController = storyboard.instantiateViewController(withIdentifier: viewControllerIdentifier) as! ViewControllerB
        self.addChildViewController(vcB)
        self.containerView.addSubview(vcB.view)
        vcB.didMove(toParentViewController: self)
        vcB.view.frame = CGRect.init(x: 0, y: 0, width: self.containerView.frame.size.width, height: self.containerView.frame.size.height)
}

同时单击 ButtonA。 Post 给 mainView 的通知。从 Container 中删除 viewController A 并添加 View Controller B .

我不喜欢使用这些,但您可以通过访问数组 childViewControllers 从父控制器获取子视图控制器。在视图加载时,您需要遍历所有这些并找到可以类型转换为视图控制器类型的类型,例如

childViewControllers.flatMap { [=13=] as? AViewController }.first

既然您找到了正确的视图控制器,我建议您将自己指定为委托

childViewControllers.flatMap { [=14=] as? AViewController }.first.delegate = self

或者简单地添加一个按钮目标

childViewControllers.flatMap { [=15=] as? AViewController }.first.button.addTarget...

现在,如果您只需同时嵌入 2 个视图控制器(有 2 个内容视图)并根据显示的内容隐藏一个或另一个,就可以轻松完成此操作。至少这样你可以立即分配连接。如果不是这种情况,那么您将需要在设置新控制器或分配初始化新视图控制器的连接时再次迭代。

在这种情况下,似乎更好地扭转系统:加载子视图控制器时调用

self.delegate = parentViewController as? AViewControllerDelegate

虽然这会起作用,但子视图控制器将控制其侦听器的人似乎是错误的,所以我建议您避免这样的编码。

我通常为容器视图使用自定义实现,您可以这样做,或者至少可以对本机视图进行子类化并定位方法,这样您的代码将类似于:

private onBPressed() {
    containerView.setViewController(viewController: BViewController(delegate: self), animation: .fade)
}