【问题标题】:Is it fine to nest a UIViewController within another without using addChildViewController?可以在不使用 addChildViewController 的情况下将 UIViewController 嵌套在另一个中吗?
【发布时间】:2018-07-09 23:41:49
【问题描述】:

我正在尝试制作一个自定义的 ContainerViewController,但由于 ViewController 转换和使所有内容都具有交互性有很多困难,我决定自己模仿该功能。

我基本上想要做的是在顶部控件上有一个分页UIScrollView(HeaderView),下面的另一个UIScrollView(ControllersView)包含ViewControllers作为页面,这样当你滑动到一个新页面时HeaderView,它还会滑动到 ControllersView 上的下一个 viewcontroller。 This is what the setup would look like.

我的问题是,上述设置有什么问题吗?将视图控制器添加到 ControllersView 中我要做的就是:controllersView.addSubview(pagecontroller1.view)

网上的一些帖子似乎说“不会调用适当的 ViewController 函数”之类的。我在这里似乎缺少什么?我猜每次 ViewController 超出框架时我需要调用的 ViewControllers 有很多解雇和承认?

澄清问题:这样做可以/有效吗?当 VC 进出框架时,我应该调用一些 viewWillAppear/disapper 函数吗?如果是这样,我应该怎么打电话?我意识到如果我要以这种方式进行设置,我需要管理很多通常是自动处理的事情,但正如我之前提到的,自定义 ContainerViewControllers 让我失望了,我会这样做。


PS。如果您似乎仍然不知道这会是什么样子,请参阅我之前的问题here,我最初想在其中使用 Container ViewController。那里有一个更好的模型。

【问题讨论】:

  • 我对好的设计感到模糊?可能是由于视图控制器(UIViewControllerUIKit 中的此类子类)和视图(UIView,应该是您放入UIScrollView 中的对象/类/子类)之间的混淆?两者都具有层次结构的潜力——也就是说,您可以拥有子视图和/或控制器。但是视图控制器的 root 视图就是这样 - 层次结构的根。有些人认为让这个根视图有六个子视图,每个子视图都有自己的视图控制器是“好的设计”。但只有当你在谈论线程时,你才应该自动这样做。
  • 结论...如果您可以将您的“Container ViewController”替换为“Container View”,则在需要时在此容器内为视图添加一个控制器,它是可能的。但是有两个UIScrollViews - 管理视图,而不是控制器 - 管理控制器?考虑用导航控制器替换一个。
  • 很抱歉,我认为我不理解您的评论。我想使用 ViewControllers 的原因是为了划分每个页面的逻辑。我会让每个视图控制器在我的应用程序中代表一个单独的“页面”。 (例如,每个视图控制器可能控制的内容包括:搜索、浏览和设置)因此,使用视图似乎非常臃肿。
  • 当你提到六个子视图部分时,我特别迷茫。基本上我想要的是一个根视图控制器,是的。不一定通过调用addChildViewController 来添加子视图控制器,因为根视图控制器不会是容器视图控制器。希望这可以澄清事情:)
  • 好的,所以接受我的“结论”评论并考虑使用工具栏而不是滚动视图。任何一个都以相同的方式工作。滚动视图管理视图而不是视图控制器。导航栏或工具栏管理视图控制器。说到臃肿,你会认为一个 3x6(顶部 x 底部)== 18 个视图的两个滚动视图比一个带有 6 个控制器的导航/工具栏更臃肿吗? (在我的世界中,“导航栏”控制器“导航”到“下一个”控制器。“工具栏”允许用户选择要使用的“工具控制器”。)

标签: ios swift uiviewcontroller uiscrollview uicontainerview


【解决方案1】:

您可以在容器视图中添加和删除 VC

对于 - 这样做可以/有效吗?当 VC 进出框架时,我应该调用一些 viewWillAppear/disapper 函数吗?如果是这样,我应该怎么称呼?

由于,我们需要在添加和删除 VC 时调用 WillAppear 和 Disappear Func,因此请尝试使用以下将处理这些响应的函数

我使用两个特定的函数在 UIView 中的 ScrollView 中的 ContainerView/UIView/SubView 中添加和删除 Controller

添加

private func add(asChildViewController viewController: UIViewController)
{
    // Configure Child View
    viewController.view.frame = CGRect(x: 0, y: 0, width: self.firstContainer.frame.size.width, height: self.firstContainer.frame.size.height)

    // Add Child View Controller
    addChildViewController(viewController)
    viewController.view.translatesAutoresizingMaskIntoConstraints = true

    // Add Child View as Subview
    firstContainer.addSubview(viewController.view)

    // Notify Child View Controller
    viewController.didMove(toParentViewController: self)
}

删除

private func remove(asChildViewController viewController: UIViewController)
{
    // Notify Child View Controller
    viewController.willMove(toParentViewController: nil)

    secondContainer.willRemoveSubview(viewController.view)

    // Remove Child View From Superview
    viewController.view.removeFromSuperview()

    // Notify Child View Controller
    viewController.removeFromParentViewController()
}

创建对象

private lazy var FirstObject: firstVC =
  {
    // Instantiate View Controller
    let viewController = self.storyboard?.instantiateViewController(withIdentifier: "firstVC") as! firstVC

    // Add View Controller as Child View Controller
    self.addChildViewController(viewController)
    return viewController
  }()

对于-controllersView.addSubview(pagecontroller1.view)

Answer - 是的,如果 pagecontroller1 未加载到内存堆栈中,则不会调用 Approbate func,以加载您需要通知 pagecontroller1 它将作为子视图添加到内存堆栈中,就像我们启动一个 Controller 和基本上是通知 Controller 将其组件加载到内存堆栈以获取一些内存分配

问题 - 可以在不使用 addChildViewController 的情况下将 UIViewController 嵌套在另一个 UIViewController 中吗?

查看苹果文档 - https://developer.apple.com/documentation/uikit/uiviewcontroller/1621394-addchildviewcontroller

这是必要的,就像通知控制器将作为子视图添加到另一个父视图中一样

示例项目

https://github.com/RockinGarg/Container_Views.git

或者

https://github.com/RockinGarg/ContainerView-TabBar.git

如果问题仍未得到解答,请告诉我你想自己处理什么功能

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多