如何在ContainerView中切换视图时关闭旧视图,确保仅显示一个视图?
修复ContainerView视图重叠问题:确保仅显示一个活跃子视图
我太懂你这个问题了——现在你的代码每次调用showSubViewInContainerView都会往容器里塞新的视图控制器,但旧的那个还留在容器里没被移除,时间一长视图就叠在一起了。问题出在你用了controller.dismiss(),这个方法是用来关闭模态弹出的视图控制器的,对容器里的子视图控制器完全没用。咱们得换个正确的方式移除旧的子控制器。
核心思路
在添加新的子视图控制器之前,先把当前容器里的旧子控制器完整地从父控制器和视图层级中移除。另外,把原来存视图ID的actualVisibleView改成直接存UIViewController?会更方便,不用再通过ID去查找,效率更高。
修改后的完整代码
// 把原来的字符串变量改成存视图控制器实例 var currentVisibleVC: UIViewController? = nil func showSubViewInContainerView(view: String){ // 1. 先移除旧的子视图控制器(如果存在) if let oldVC = currentVisibleVC { // 通知系统该控制器即将被移除 oldVC.willMove(toParentViewController: nil) // 从视图层级中删除旧视图 oldVC.view.removeFromSuperview() // 正式从父控制器中移除 oldVC.removeFromParentViewController() print("Zamykam: \(oldVC.restorationIdentifier ?? "Nieznany widok")") } // 2. 添加新的子视图控制器 let controller = storyboard!.instantiateViewController(withIdentifier: view) addChildViewController(controller) controller.view.translatesAutoresizingMaskIntoConstraints = false systemContainerView.addSubview(controller.view) NSLayoutConstraint.activate([ controller.view.leadingAnchor.constraint(equalTo: systemContainerView.leadingAnchor), controller.view.trailingAnchor.constraint(equalTo: systemContainerView.trailingAnchor), controller.view.topAnchor.constraint(equalTo: systemContainerView.topAnchor), controller.view.bottomAnchor.constraint(equalTo: systemContainerView.bottomAnchor) ]) controller.didMove(toParentViewController: self) // 更新当前活跃的视图控制器 currentVisibleVC = controller print("OTWIERAM: \(view)") }
关键步骤解释
移除旧控制器的标准流程:
willMove(toParentViewController: nil):触发控制器的生命周期钩子,告诉系统它即将脱离父控制器oldVC.view.removeFromSuperview():彻底把旧视图从容器的视图树中删除,释放视图资源oldVC.removeFromParentViewController():将控制器从父控制器的子控制器列表中移除,完成整个解除关联的流程
变量类型优化:用
currentVisibleVC直接存储当前活跃的视图控制器实例,比存字符串ID更直接,避免重复查找,也减少了因ID拼写错误导致的问题
这样修改之后,每次打开新视图时,旧视图都会被彻底清理,容器里就只会保留一个活跃的子视图啦~
内容的提问来源于stack exchange,提问作者triff
相关产品推荐
相关产品推荐

