使用Swift 4 +,iOS 11.4 +,Xcode 10 +
我正在使用带有导航控制器的ContainerView来加载多个ViewController。
此外,保存ContainerView的ViewController也被推送到另一个NavigationController堆栈上。
请参见下图:
“菜单”是堆栈中的根控制器。我将另一个ViewController(TopViewController)推送到同一堆栈上-到目前为止一切顺利。
我的问题是我想用不同的ViewController(Item1)“预加载” TopViewController> ContainerView。之前 TopViewController变得可见。
除了Item1之外,还有其他ViewController以这种方式需要“预加载”。
我尝试在TopViewController中使用“ viewDidLoad”来推送Item1,
toVC = storyboard?.instantiateViewController(withIdentifier: "Item1") as! Item1
TopNav.pushViewController(toVC, animated: true)
并且有效-但仅在TopViewController可见之后。这意味着您可以在视图中看到Item1“弹出”,而不是已经可见。
我也在Menu VC中尝试了此代码,但它没有将任何内容推送到ContainerView上。
let toVC = self.storyboard?.instantiateViewController(withIdentifier: "TopViewController") as! TopViewController
// Tried this to 'pre-load' the next VC - shows no VC, and disables 'back' navigation
let toNav = toVC.navigationController
let nextVC = storyboard?.instantiateViewController(withIdentifier: "Item1") as! Item1
// Neither of the lines below loads the Item1 VC....
//toNav?.viewControllers = [nextVC]
toNav.pushViewController(toVC, animated: true)
如何在带有ContainerView的VC可见之前将Item1推送到ContainerView的导航堆栈上?
FYI:您可以在这里下载我的示例项目:https://gitlab.com/whoit/newviews
TopNav.pushViewController(toVC, animated: true)
并且它有效-但仅在TopViewController可见之后。
因为您要求动画。如果需要的话,将animated: true
更改为animated: false
。以上是正确的,但是您的项目还有很多其他问题。
最重要,您的容器视图没有约束。这将导致其尺寸错误。在情节提要中赋予它约束。
第二,做我上面说的:用
第三,您需要像这样预先加载顶视图控制器的视图:toVC
动画推动false
。
@IBAction func Item1_Tap(_ sender: UIButton) { let toVC = self.storyboard?.instantiateViewController( withIdentifier: "TopViewController") as! TopViewController toVC.loadViewIfNeeded() // add this line // then delete all the other useless stuff
结果:
另一种方法会将TopViewController
嵌入到TabBarController
中,并隐藏标签栏。然后,当选择一个项目时,您将TopViewController
与该项目相关联的标签索引加载。
编辑:
您可以做的是用导航控制器代替TopViewContorller
,该控制器根据所选项目设置rootViewController
。就您的代码而言,需要一些维护工作才能使此工作顺利进行:
摆脱基数UINavigationController
,并将MenuViewController
用作初始的ViewController
。
UINavigationController
相同的每个项目上添加标记)。>MenuViewController
中覆盖prepare(for:, sender:)
,并初始化与所选项目关联的UIViewController
。您可以通过命名segue并打开名称,或将发送方与按钮匹配来进行此操作。override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "item1Segue":
guard let item1VC = storyboard?.instantiateViewController(withIdentifier: "Item1") else { return assertionFailure() }
item1VC.title = "Item1"
(segue.destination as UINavigationController)?.setViewControllers([item1VC], animated: false)
case "item2Segue":
guard let item2VC = storyboard?.instantiateViewController(withIdentifier: "Item2") else { return assertionFailure() }
item2VC.title = "Item2" UINavigationController)?.setViewControllers([item2VC], animated: false)
// And so on
}
}
要获得与TopViewController
相同的UI,请在Item viewControllers中添加一个后退和长条按钮,标题之后是按代码所示设置标题。