iOS中如何打开栈内已存在的ViewController而非新建
Hey there! I get it—dealing with duplicate view controllers cluttering up your navigation stack can be super frustrating. Let’s walk through exactly how to reuse your existing V1 instance instead of spawning a new one when navigating from V3.
The Core Issue
Your current code creates a brand-new V1 every time you call pushViewController, which ends up with a stack like: V1 → V2 → V3 → V1 (new). What you actually want is to jump back to the original V1 that’s already sitting in the stack.
Solution: Locate & Pop to the Existing Instance
Instead of pushing a fresh V1, we’ll first scan the navigation stack for an existing V1 instance. If we find it, we’ll pop directly to it (which clears out all controllers above it—V2 and V3 in your flow). If for some reason it doesn’t exist (a safe fallback), we’ll create a new one.
Here’s the code you can drop into V3:
// First, confirm we have access to the navigation controller guard let navController = navigationController else { print("No navigation controller available") return } // Search the stack for an existing V1 instance if let existingV1 = navController.viewControllers.first(where: { $0 is V1 }) { // Optional: If V1 needs fresh data when we return, cast and call a refresh method if let v1 = existingV1 as? V1 { v1.refreshContent() // Replace with your actual refresh logic } // Animate back to the existing V1 navController.popToViewController(existingV1, animated: true) } else { // Fallback: Only create a new V1 if it's not already in the stack let newV1 = V1(nibName: "V1", bundle: nil) navController.pushViewController(newV1, animated: true) }
How This Works
first(where: { $0 is V1 })scans the stack from the root (oldest) to the top (newest) and grabs the firstV1it finds—ideal for yourV1 → V2 → V3flow.popToViewControllersmoothly animates the transition back toV1and removes all controllers between the current top (V3) andV1from the stack, leaving only your originalV1intact.
Optional: Custom Stack Adjustments (For Edge Cases)
If you ever need to keep certain controllers in the stack alongside V1 (not needed for your current flow, but useful for other scenarios), you can directly modify the stack with setViewControllers:
// Example: Keep V1 and retain V3 (not recommended for your use case, but just for reference) let updatedStack = navController.viewControllers.filter { $0 is V1 } + [self] navController.setViewControllers(updatedStack, animated: true)
Pro Tip: Refresh V1 on Return
If V1 needs to update its content when you navigate back, either call a custom refresh method before popping (like in the example) or override viewWillAppear in V1 to trigger updates whenever it becomes visible:
class V1: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Refresh your data here loadLatestContent() } }
内容的提问来源于stack exchange,提问作者Sanjay Kumar

