【问题标题】:Show a View Controller that is already on Navigation Stack显示一个已经在导航堆栈上的视图控制器
【发布时间】:2016-11-14 16:23:45
【问题描述】:

我有一个标签栏控制器(带有底部菜单)和一个顶部菜单。问题是我不想将黄色和绿色视图链接到选项卡栏(因为用户将使用顶部菜单而不是底部菜单更改视图)。

我遇到一个问题,每次单击按钮时,都会堆叠一个新的视图实例(所以我最终会得到 V1 -> V2 -> V3 -> V2 -> V4 等)

我的部分解决方案是做这样的事情:

@IBAction func yellowViewButtonAction(_ sender: AnyObject)
{
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "YelloViewController") as! YelloViewController

    if let viewControllers = navigationController?.viewControllers {
        for viewController in viewControllers {
            // some process
            if viewController is YelloViewController {
                print("View is on stack")
            }
        } 

         let storyboard = UIStoryboard(name: "Main", bundle: nil)
         let controller = storyboard.instantiateViewController(withIdentifier: "YelloViewController") as! YelloViewController
         self.navigationController?.pushViewController(controller, animated: false)
    }
}

我可以看到视图位于导航堆栈上,因为for 中的if 语句是true。问题是,我怎样才能检索它而不是推送同一视图的新实例? (因为除了当前存在的巨大内存问题外,我还丢失了视图中的所有数据)。

我想保持堆栈上的所有内容完好无损。

例子:

V1 -> V2 -> V3 -> V4(当前视图)

如果我从 V4 回到 V1,我仍然希望在导航控制器堆栈上拥有 V4、V3 和 V2。

另一个问题是,如果这个解决方案是苹果可能会拒绝的东西。

感谢您的帮助。

【问题讨论】:

    标签: ios swift3 navigationcontroller


    【解决方案1】:

    看起来您不使用并且需要导航控制器。每当您调用self.navigationController?.pushViewController(controller, animated: false) 时,该控制器的一个新实例就会进入堆栈。

    理想情况下,您会从您导航的视图控制器中调用 popViewController。在创建标签栏控制器的自定义行为时,至少在我看来,很难完全按照您的计划获得导航逻辑。

    在这种情况下,我通常会手动显示和隐藏视图控制器。

    @IBAction func didPressTab(sender: UIButton) {
            let previousIndex = selectedIndex
            selectedIndex = sender.tag
            buttons[previousIndex].selected = false
            let previousVC = viewControllers[previousIndex]
            previousVC.willMoveToParentViewController(nil)
            previousVC.view.removeFromSuperview()
            previousVC.removeFromParentViewController()
            sender.selected = true
            let vc = viewControllers[selectedIndex]
            addChildViewController(vc)
            vc.view.frame = contentView.bounds
            contentView.addSubview(vc.view)
            vc.didMoveToParentViewController(self)
    
        }
    

    每个“导航按钮”都有唯一的 id 并调用 didPressTab 函数。

    我实际上是从本教程中学到的:https://github.com/codepath/ios_guides/wiki/Creating-a-Custom-Tab-Bar

    【讨论】:

    • 我确实需要一个导航控制器,因为当我按下黄色和绿色视图时,我仍然可以看到底部栏菜单。就像我说的那样,我希望视图保持不变,如果我弹出,我将丢失视图上的所有数据。
    • 您不需要导航控制器来查看底部菜单栏。查看链接中的教程,您会看到:) 此外,我提供的代码仅移动视图,因此这些视图控制器的“内部”状态保持不变。
    • 我想说的是,我不想要自定义底部菜单栏,因为我已经有了一个。我希望能够在导航控制器堆栈中的视图之间进行更改。
    • 这就是我想说的:) 使用您已经存在的底部菜单。每当您单击菜单元素时,我猜您的代码中的某些操作已执行,因此只需添加我发布的代码以在视图控制器之间切换,根据您的需要对其进行一些调整(变量名称等),它应该可以工作
    • 感谢回购。你的想法实际上给了我另一个想法,我最终使用 Container View 来处理我的所有视图。但是感谢您的想法。
    【解决方案2】:

    弹出视图控制器,直到指定的视图控制器位于导航堆栈的顶部。

    参考 - https://developer.apple.com/documentation/uikit/uinavigationcontroller

    func popToViewController(UIViewController, animated: Bool) -> [UIViewController]?
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多