如何在 Swift 上的两个 child 视图控制器之间切换?
How can I switch between two child View Controllers on Swift?
我正在尝试在特定 Container View
上的两个 child View Controllers
之间切换。我有一个带菜单的 Navigation Controller
(Table View
来制作菜单的不同选项)。
每次单击菜单的一个选项时,我都想更改 Container View
的 child,但我得到的是 Navigation bar
上方的 child 和 Table View
(它们未显示,但它们位于新的 child 视图控制器下)。
我的Main.storyboard的方案是这样的:
Navigation Controller --> View Controller (With 2 Container View, 1 for Table View
and the other to set master View Controller)
|
|
------------------------
| |
View Controller Table View
(id: master)
View Controller (id: Home) View Controller (id: screen2)
我在 tableView
函数中有以下代码(我在其中检测到何时单击菜单选项)来更改容器视图的 child 视图控制器:
let currentController = self.navigationController?.visibleViewController //container
var oldChild = (currentController?.childViewControllers.last!)! as UIViewController //master
let newChild = (storyboard?.instantiateViewControllerWithIdentifier("Home"))! as UIViewController //Home
if (oldChild != newChild){
if currentController.childViewControllers.last != nil{
oldChild.willMoveToParentViewController(nil)
currentController.navigationController?.navigationBar.willRemoveSubview(oldChild.view)
//oldChild.view.removeFromSuperview()
oldChild.removeFromParentViewController()
}
currentController.addChildViewController(newChild)
currentController.view.addSubview(newChild.view)
newChild.didMoveToParentViewController(currentController)
}
此代码运行良好。问题是新的 child 视图控制器显示在导航栏和 Table 视图(菜单)上方。所以它占据了整个屏幕而不是适合容器视图。
我应该在我的代码中添加更多内容还是我使用代码的方式不对?我已经搜索了很多,但大多数解决方案都在 objective-c 中或对我不起作用。
编辑: 在搜索了很多小时后,我怀疑它与连接根 View Controller
和 master
的嵌入式转场有关查看控制器,但我无法将新的 child 嵌入到 Container View
。我正在尝试的代码是:
currentController.performSegueWithIdentifier("EmbedSegue", sender: newChild)
或
currentController.presentViewController(newChild, animated: true, completion: nil)
但其中 none 嵌入了 segue。全屏显示newChild
即可。
提前致谢!
在调用 currentController.addChildViewController(newChild)
之前,试试这个:
newChild.modalPresentationStyle = .CurrentContext
这应该在容器视图的范围内显示 newChild
视图控制器,而不是全屏显示。
你不想使用 presentViewController,我也不认为使用 segue 是正确的,那些会导致全屏覆盖。
我认为你本来就在正确的轨道上,你需要视图还是视图控制器?
对于 UIView,您可以轻松地用您想要的值填充您的视图,然后用您的新视图替换您的容器视图,您还可以为 xib 或故事板场景加载 UIView。
对于 UIViewController,我想如果你在它们的视图生命周期方法中有特定的逻辑,你需要将它们添加为子视图控制器并再次用 viewController.view 替换容器视图。
最后,您只需触发 didselectrowatindexpath
方法中的逻辑。只需尝试一个基本示例,创建一个具有橙色背景颜色的 UIView 并执行 self.containerView = orangeView
.
如果不清楚,请告诉我,如有必要,我很乐意提供代码示例。
你应该有 ContainerView 的 IBOutlet 和 addSubview 到这个 IBOutlet
currentController.containerView.addSubview(newChild.view)
或
currentController.addSubview(childView.view, toView: self.containerView)
//set off the viewcontroller UNDERTOPBAR property off. your VC will load in currentControllers view. you need to set the frame of the view that your are going to load.
currentController.addChildViewController(newChild)
newChild.view.frame = CGRectMake(self.currentController.bounds.origin.x, self.currentController.bounds.origin.y, self.currentController.bounds.size.width, self.currentController.bounds.size.height)
currentController.view.addSubview(newChild.view)
newChild.didMoveToParentViewController(currentController)
制作容器的出口并像这样添加您的子控制器:self.addSubview(self.currentViewController!.view, toView: self.containerView)
可能对你有帮助。
问题已得到解答,但正如我在您的代码中看到的那样,我建议您将子视图的边缘固定到父视图的边缘。如下:
child.view.translatesAutoresizingMaskIntoConstraints = false
child.view.topAnchor.constraint(equalTo: parent.view.topAnchor).isActive = true
child.view.bottomAnchor.constraint(equalTo: parent.view.bottomAnchor).isActive = true
child.view.leadingAnchor.constraint(equalTo: parent.view.leadingAnchor).isActive = true
child.view.trailingAnchor.constraint(equalTo: parent.view.trailingAnchor).isActive = true
我正在尝试在特定 Container View
上的两个 child View Controllers
之间切换。我有一个带菜单的 Navigation Controller
(Table View
来制作菜单的不同选项)。
每次单击菜单的一个选项时,我都想更改 Container View
的 child,但我得到的是 Navigation bar
上方的 child 和 Table View
(它们未显示,但它们位于新的 child 视图控制器下)。
我的Main.storyboard的方案是这样的:
Navigation Controller --> View Controller (With 2 Container View, 1 for Table View
and the other to set master View Controller)
|
|
------------------------
| |
View Controller Table View
(id: master)
View Controller (id: Home) View Controller (id: screen2)
我在 tableView
函数中有以下代码(我在其中检测到何时单击菜单选项)来更改容器视图的 child 视图控制器:
let currentController = self.navigationController?.visibleViewController //container
var oldChild = (currentController?.childViewControllers.last!)! as UIViewController //master
let newChild = (storyboard?.instantiateViewControllerWithIdentifier("Home"))! as UIViewController //Home
if (oldChild != newChild){
if currentController.childViewControllers.last != nil{
oldChild.willMoveToParentViewController(nil)
currentController.navigationController?.navigationBar.willRemoveSubview(oldChild.view)
//oldChild.view.removeFromSuperview()
oldChild.removeFromParentViewController()
}
currentController.addChildViewController(newChild)
currentController.view.addSubview(newChild.view)
newChild.didMoveToParentViewController(currentController)
}
此代码运行良好。问题是新的 child 视图控制器显示在导航栏和 Table 视图(菜单)上方。所以它占据了整个屏幕而不是适合容器视图。
我应该在我的代码中添加更多内容还是我使用代码的方式不对?我已经搜索了很多,但大多数解决方案都在 objective-c 中或对我不起作用。
编辑: 在搜索了很多小时后,我怀疑它与连接根 View Controller
和 master
的嵌入式转场有关查看控制器,但我无法将新的 child 嵌入到 Container View
。我正在尝试的代码是:
currentController.performSegueWithIdentifier("EmbedSegue", sender: newChild)
或
currentController.presentViewController(newChild, animated: true, completion: nil)
但其中 none 嵌入了 segue。全屏显示newChild
即可。
提前致谢!
在调用 currentController.addChildViewController(newChild)
之前,试试这个:
newChild.modalPresentationStyle = .CurrentContext
这应该在容器视图的范围内显示 newChild
视图控制器,而不是全屏显示。
你不想使用 presentViewController,我也不认为使用 segue 是正确的,那些会导致全屏覆盖。
我认为你本来就在正确的轨道上,你需要视图还是视图控制器?
对于 UIView,您可以轻松地用您想要的值填充您的视图,然后用您的新视图替换您的容器视图,您还可以为 xib 或故事板场景加载 UIView。
对于 UIViewController,我想如果你在它们的视图生命周期方法中有特定的逻辑,你需要将它们添加为子视图控制器并再次用 viewController.view 替换容器视图。
最后,您只需触发 didselectrowatindexpath
方法中的逻辑。只需尝试一个基本示例,创建一个具有橙色背景颜色的 UIView 并执行 self.containerView = orangeView
.
如果不清楚,请告诉我,如有必要,我很乐意提供代码示例。
你应该有 ContainerView 的 IBOutlet 和 addSubview 到这个 IBOutlet
currentController.containerView.addSubview(newChild.view)
或
currentController.addSubview(childView.view, toView: self.containerView)
//set off the viewcontroller UNDERTOPBAR property off. your VC will load in currentControllers view. you need to set the frame of the view that your are going to load.
currentController.addChildViewController(newChild)
newChild.view.frame = CGRectMake(self.currentController.bounds.origin.x, self.currentController.bounds.origin.y, self.currentController.bounds.size.width, self.currentController.bounds.size.height)
currentController.view.addSubview(newChild.view)
newChild.didMoveToParentViewController(currentController)
制作容器的出口并像这样添加您的子控制器:self.addSubview(self.currentViewController!.view, toView: self.containerView)
可能对你有帮助。
问题已得到解答,但正如我在您的代码中看到的那样,我建议您将子视图的边缘固定到父视图的边缘。如下:
child.view.translatesAutoresizingMaskIntoConstraints = false
child.view.topAnchor.constraint(equalTo: parent.view.topAnchor).isActive = true
child.view.bottomAnchor.constraint(equalTo: parent.view.bottomAnchor).isActive = true
child.view.leadingAnchor.constraint(equalTo: parent.view.leadingAnchor).isActive = true
child.view.trailingAnchor.constraint(equalTo: parent.view.trailingAnchor).isActive = true