如何检查视图控制器是不是添加到堆栈中
Posted
技术标签:
【中文标题】如何检查视图控制器是不是添加到堆栈中【英文标题】:How to check viewcontroller is added in stack or not如何检查视图控制器是否添加到堆栈中 【发布时间】:2017-03-16 05:33:50 【问题描述】:我有两个视图控制器。通过按下按钮使用下面的代码,我已经从一个视图导航到另一个视图。
*let secondViewController = self.storyboard!.instantiateViewControllerWithIdentifier("NotificationController") as! NotificationController
self.navigationController!.pushViewController(secondViewController, animated: true)*
对于后面,我使用下面的代码在 bar 按钮上使用 bar button click for back。
self.navigationController?.popViewControllerAnimated(true)
所以我的问题是,如果我不断地从一个视图转到另一个视图,那么它会添加到堆栈中。我只想显示另一个视图,当它已经添加到堆栈中以停止添加它。它只添加一次。
【问题讨论】:
***.com/a/42523549/5461400 试试这个yourViewController.view.window != nil
【参考方案1】:
要检查导航堆栈是否包含特定类型的view controller
,您可以使用:
if let viewControllers = self.navigationController?.viewControllers
if viewControllers.contains(where:
return $0 is YourViewController
)
//Write your code here
要从导航堆栈中删除特定控制器,您需要对导航堆栈进行更改。
示例:
if var viewControllers = self.navigationController?.viewControllers
for controller in viewControllers
if controller is UIViewController
viewControllers.removeElement(controller)
self.navigationController?.viewControllers = viewControllers
【讨论】:
Array 上没有 'removeElement()' 方法。但是您可以通过过滤 viewControllers 属性来执行相同的操作。请参阅我的答案以获取示例,并详细说明您的答案。干杯。【参考方案2】:对于 swift 4,您可以使用
if let viewControllers = self.navigationController?.viewControllers
for vc in viewControllers
if vc.isKind(of: YourViewController.classForCoder())
print("It is in stack")
//Your Process
【讨论】:
【参考方案3】:针对 Swift 4.1 详细阐述 PGDev 的答案
如何从UINavigationController
堆栈中删除特定的UIViewController
子类:
/// Given 'nc' is a valid UINavigationController instance,
/// removes all instances of MyViewController from the stack
nc.viewControllers = nc.viewControllers.filter !($0 is MyViewController)
把它作为一个扩展:
extension UINavigationController
/// Given the kind of a (UIViewController subclass),
/// removes any matching instances from self's
/// viewControllers array.
func removeAnyViewControllers(ofKind kind: AnyClass)
self.viewControllers = self.viewControllers.filter !$0.isKind(of: kind)
/// Given the kind of a (UIViewController subclass),
/// returns true if self's viewControllers array contains at
/// least one matching instance.
func containsViewController(ofKind kind: AnyClass) -> Bool
return self.viewControllers.contains(where: $0.isKind(of: kind) )
用法:
guard let nc = self.navigationController else return
let exists = nc.containsViewController(ofKind: MyViewController.self)
nc.removeAnyViewControllers(ofKind: MyViewController.self)
顺便说一句,如果有人知道如何将 'kind' 限制在 UIViewController 的子类中,请大声说出来。
【讨论】:
func containsViewController(ofKind kind: UIViewController.Type) -> Bool return self.viewControllers.contains(where: $0.isKind(of: kind) ) 【参考方案4】:这是检查它的代码。
if let viewControllers = navigationController?.viewControllers
for viewController in viewControllers
// some process
if viewController.isKindOfClass(ViewControllerClassName)
println("yes it is")
【讨论】:
添加时如何在栈中移除 vc.removeFromParentViewController- 使用这个方法 如果你知道索引号,你也可以使用这个 self.navigationController?.viewControllers.removeAtIndex(vcIndex) 您觉得这有帮助吗? 当我再次从堆栈中移除时。它没有通过使用此代码添加到堆栈中。【参考方案5】:extension UINavigationController
public func hasViewController(ofKind kind: AnyClass) -> UIViewController?
return self.viewControllers.first(where: $0.isKind(of: kind))
使用
self.navigationController.hasViewController(ofKind: #ViewControllerName#.self)
【讨论】:
【参考方案6】:您可以通过以下code
查看
目标 - C
NSArray * controllers = [self.navigationController viewControllers];
for (int i = 0; i < [controllers count]; i++)
UIViewController * controllerTest = [controllers objectAtIndex:i];
if([controllerTest isKindOfClass:[YourController class]])
NSLog(@"Class is available");
斯威夫特 3.0
if let viewControllers = self.navigationController?.viewControllers
for viewController in viewControllers
// some process
if viewController.isKindOfClass(YourController)
print("Class is available")
【讨论】:
如何在类可用时删除或仅显示而不添加堆栈【参考方案7】:我们开始吧。
这一行会给你一个 UIViewControllers 数组
self.navigationController?.viewControllers
现在你要做的是检查你的 viewControllerObject 是否存在?
通过写这行
if viewController.isKindOfClass(YourController)
这是一个完整的代码。
if let viewControllers = self.navigationController?.viewControllers
for viewController in viewControllers
if viewController.isKindOfClass(YourController)
print("Your controller exist")
当您在返回“ViewControllerA”时写下一行时,它将从导航堆栈中删除一个 ViewControllerB。
self.navigationController?.popViewControllerAnimated(true)
这与我们对堆栈进行的弹出操作类似,而导航控制器是一个堆栈。
如果您有任何困惑,请告诉我。
【讨论】:
【参考方案8】:Swift 5(工作测试)。 检查视图控制器是否堆叠在导航中的更好方法是简单地询问视图控制器的可访问性。参见示例 下面。我使用这个 sn-p 回到以前的视图控制器。
if self.navigationController?.accessibilityActivate() != nil
self.navigationController?.popViewController(animated: true)
else
self.dismiss(animated: true, completion: nil)
【讨论】:
【参考方案9】:这是另一个独奏:
guard let controllersInStack = navigationController?.viewControllers else return
if let yourViewController = controllersInStack.first(where: $0 is YourViewController )
// Do what you want with yourViewController
【讨论】:
【参考方案10】:您只需检查视图控制器的 nibName 即可获得结果
下面的这段代码将确保您不会在 navigatoinController 中再次添加一个 viewController,
var VC = YourViewController
var objVC = (storyboard.instantiateViewController(withIdentifier: "YourViewController"))
if navigationController.viewControllers.contains(where: (VC) -> Bool in
return objVC.nibName == VC.nibName
)
for (i,controller) in navigationController.viewControllers.enumerated()
if controller.isKind(of: VC)
navigationController.viewControllers.remove(at: i)
navigationController.pushViewController(objVC, animated: false)
elsenavigationController.pushViewController(objVC, animated: false)
如果你只是想检查 viewController 是否在 NaviagtionController 中,那么试试这个:
var checkForView = navigationController.viewControllers.contains(where: (VC) -> Bool in
return objVC.nibName == VC.nibName
)
【讨论】:
以上是关于如何检查视图控制器是不是添加到堆栈中的主要内容,如果未能解决你的问题,请参考以下文章