我有一个应用程序,有两个故事板,一个选项卡条控制器和6+ viewControllers嵌入到他们自己的navigationControllers中。
在所有VC中,我以CartViewController的方式呈现barButtonItem,而在购物车中,我从tableViewCell中呈现CustomersVC。我的问题是,当我从购物车中呈现客户时,我可以再次从CustomersVC到购物车,然后继续循环。
假设
我的假设是,如果我从anyVC以模式方式显示购物车,然后从cart以模式方式显示navigationController,然后显示CustomersVC,则会存在这样一个数组:
viewController
为了解决这个问题,如果从购物车中调用"ViewCart“barButtonItem,我将从customersVC中删除它。我的问题是,我无法设法遍历堆栈来检查它。我在这里尝试过几种方法,但都没有用。
我知道我可以使用委托和设置变量来显示/隐藏按钮,但我渴望学习,并且希望它更健壮,而不必记住手动设置和重置var。
有什么建议吗?
代码
extension UIViewController {
@objc func viewCart() {
if Cart.sharedInstance.order.items.count != 0 {
let storyboard = UIStoryboard(name: "Cart", bundle: nil)
if let cartVC = storyboard.instantiateViewController(withIdentifier: "Cart") as? CartViewController {
let cartNavigationController = UINavigationController(rootViewController: cartVC)
self.present(cartNavigationController, animated: true)
}
}
}
}
Class CartViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let customersNC = storyboard.instantiateViewController(withIdentifier: "CustomersNC") as? UINavigationController {
present(customersNC, animated: true)
}
class CustomersTableViewController {
override func viewDidLoad() {
// Tried presentingViewController:
if let CartVC = presentingViewController as? CartViewController {
myButton.isEnabled = false
}
// Tried navigationController?.viewControllers:
guard let controllersInStack = navigationController?.viewControllers else { return }
if let CartVC controllersInStack.first(where: { $0 is CartViewController }) as? CartViewController {
myButton.isEnabled = false
}
// Tried an extension I found here https://stackoverflow.com/questions/38583941/get-all-list-of-uiviewcontrollers-in-ios-swift, but it returns nil
extension UIViewController {
/**
* Traverses the entire VC hirearchy downwards and collects VC'w that are of speccific PARAM: type
* - Fixme: ⚠️️ this can be written more elegantly with flatMap
* ## Example:
* let vc: CustomVC? = UIApplication.shared.delegate?.window?.rootViewController?.descendants().first
*/
func descendants<T>(type: T.Type? = nil) -> [T] {
var childrenOfType: [T] = []
self.children.forEach {
if let child: T = ($0 as? T) {
childrenOfType.append(child)
}
if !$0.children.isEmpty {
childrenOfType += $0.descendants(type: type)
}
}
return childrenOfType
}
}发布于 2020-05-29 19:25:19
每个视图控制器都有一个parent或一个presentingViewController (或者两者都有),因此通过询问这些内容,您可以确定“您在哪里”。
这通常足以告诉您情况,特别是如果您明智地使用类类型(例如,您可以使导航控制器不同的UINavigationController子类只是为了知道您以后在哪里)。
如果您想要一个完整的视图控制器链的简介到您所在的位置,您可以递归地在该链上跟踪您的方式,如下所示:
func trace(_ vc: UIViewController) {
print(vc)
if let parent = vc.parent {
print("parent:")
trace(parent)
return
}
if let presenter = vc.presentingViewController {
print("presenter:")
trace(presenter)
return
}
print("done")
}该示例输出的不是一个视图控制器列表,而是每个视图控制器之间连接的性质(这是您真正需要的),但是通过从链中的“最后”视图控制器调用它,您可以在想要说“不要再深入一点”的时候,对链的样子有一个心理上的了解。
下面是一个更完整的示例,演示如何将反向跟踪积累到数组中:
class MyVC: UIViewController {
func makeTrace() {
super.viewDidAppear(animated)
let result = self.trace([(.start, self)])
print(result)
}
enum Link: String {
case parent
case presenter
case start
}
typealias Chain = [(Link, UIViewController)]
func trace(_ chain: Chain) -> Chain {
if let parent = chain.last!.1.parent {
return trace(chain + [(.parent, parent)])
}
if let presenter = chain.last!.1.presentingViewController {
return trace(chain + [(.presenter, presenter)])
}
return chain
}
}所以result会告诉你足够多的信息,让你知道“你在哪里”。
https://stackoverflow.com/questions/62092946
复制相似问题