在显示之前将ViewController加载到ContainerView中,因此看不到任何过渡

时间:2018-12-31 18:18:49

标签: ios swift xcode uinavigationcontroller

使用Swift 4 +,iOS 11.4 +,Xcode 10 +

我正在使用带有导航控制器的ContainerView来加载多个ViewController。

此外,保存ContainerView的ViewController也被推送到另一个NavigationController堆栈上。

查看下图:

enter image description here

“菜单”是堆栈中的根控制器。 我将另一个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的导航堆栈中?

仅供参考:您可以在此处下载我的示例项目:https://gitlab.com/whoit/newviews

2 个答案:

答案 0 :(得分:0)

   TopNav.pushViewController(toVC, animated: true)
     

它有效-但仅在To​​pViewController可见之后。

因为您要求动画。如果需要的话,将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

结果:

enter image description here

答案 1 :(得分:0)

我认为您想要的是一种管理子视图控制器的方法,对吗? (childVC1 = item1,childVC2 = item2,依此类推)

如果是这种情况,请this may help

另一种方法是将TopViewController嵌入到TabBarController中,然后隐藏标签栏。然后,当一个项目被选中时,您将TopViewController与该项目相关联的标签索引加载。

编辑:

您可以做的是在您的TopViewContorller上放置一个导航控制器,该控制器根据所选项目设置rootViewController。就您的代码而言,需要一些维护工作才能使此工作顺利进行:

  1. 摆脱基础UINavigationController的影响,并将MenuViewController作为初始的ViewController
  2. 在与同一UINavigationController相同的每个项目上添加标记。
  3. 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中添加一个后退和长条按钮,标题后面将设置代码中所示的标题。