显示一个已经在导航堆栈上的视图控制器
Posted
技术标签:
【中文标题】显示一个已经在导航堆栈上的视图控制器【英文标题】: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。
另一个问题是,如果这个解决方案是苹果可能会拒绝的东西。
感谢您的帮助。
【问题讨论】:
【参考方案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]?
【讨论】:
以上是关于显示一个已经在导航堆栈上的视图控制器的主要内容,如果未能解决你的问题,请参考以下文章