iOS - 编程方式设置UIContainerView的嵌入UIViewController

3
我有一个UIViewController,里面嵌套了一个UIContainerView。根据某些条件是否满足,我想通过编程的方式将容器视图的嵌入视图设置为不同的UIViewController。 我注意到你只能有一个嵌入segue来设置一个UIViewController,那么有没有办法完成这个过程呢?
我试着将我的容器视图设置为输出口,但我找不到任何方法来设置嵌入的UIViewController。 任何关于如何开始此问题的建议都将不胜感激。

你真正想要实现什么? - Hermann Klecker
不要混合使用Storyboard和编程设置,一次只做一件事。虽然混合使用没有问题,但在完全理解Storyboard的工作原理之前,您可能会感到困惑。 - Hermann Klecker
你可能想要重写 - prepareForSegue:sender: 方法,以便根据第三方条件管理不同的segue。或者不使用segue,而是通过编程方式导航到新的视图控制器,或者使用 - performSegueWithIdentifier:sender: 方法从story board中调用特定的segue。 - Hermann Klecker
2个回答

7

如果你的意思是交换UIViewControllerUIViews,那么我认为你的想法是错误的(希望我理解了你的概念)。

UIViewController应该只有一个设计好的UIView并且应该管理该视图的值。正如你所说,你可以使用Containers,但是你应该添加一个带有它自己视图的UIViewController,这样就有一个实例来管理该视图。你的第一个UIViewController应该只添加/删除那个ChildViewController

因此,我建议:

UIViewController上实现一个类别,并添加以下方法:

- (void)displayContentController:(UIViewController *)content {
    [self addChildViewController:content];
    content.view.frame = [[UIScreen mainScreen] bounds];
    [self.view addSubview:content.view];
    [content didMoveToParentViewController:self];
}

- (void)hideContentController:(UIViewController *)content {
    [content willMoveToParentViewController:nil];
    [content.view removeFromSuperview];
    [content removeFromParentViewController];
}

创建AViewControllerBViewController。在AViewController中调用(viewDidLoad?):
BViewController *bViewController = [[BViewController alloc] init];
[self displayContentController:bViewController];

BViewController中管理该控制器的视图,AViewController应仅负责管理何时显示BViewController以及何时隐藏它。
如果我误解了您的问题,请在评论中指出,我将删除此答案。

这实际上是一种非常聪明的做法。其他帖子提到了创建自定义容器视图控制器,但这种方法需要最少的复杂性和思考时间。谢谢! :) - Rafi
根据文档,你的两个方法都应该调用willMovedidMove - Rivera
@Rivera 来自苹果文档的内容:removeFromParentViewController() 方法在移除子视图后会自动调用子视图控制器的 didMove(toParentViewController:) 方法。而当你的自定义容器调用 addChildViewController(_:) 方法时,它会在添加子视图控制器之前自动调用将要移动到父视图控制器的 willMove(toParentViewController:) 方法。希望这能解决你的疑问。 - Nat

0
受 Vive 回答的启发:
extension UIViewController {

    func showContentController(_ controller: UIViewController, containerView: UIView? = nil) {
        controller.willMove(toParentViewController: self)
        self.addChildViewController(controller)
        controller.view.frame = (containerView ?? self.view).frame
        (containerView ?? self.view).addSubview(controller.view)
        controller.view.autoPinEdgesToSuperviewEdges()
        controller.didMove(toParentViewController: self)
    }

    func hideContentController(_ controller: UIViewController) {
        controller.willMove(toParentViewController: nil)
        controller.removeFromParentViewController()
        controller.view.removeFromSuperview()
        controller.didMove(toParentViewController: nil)
    }
}

这种重复调用 will/didMove 的做法不仅没有必要,而且会导致 willMovedidMove 被调用两次,这是无效的。请参考我在上面带有苹果文档引用的评论。 - Nat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接