I'm starting a navigation flow. I'm starting from AViewController and I'm navigating in app. AViewController -> BViewController -> CViewController -> DViewController. While in DViewController, I want to push EViewController. But I want AViewController to do this push, not DViewController. So I want my presentingViewController to be AViewController. With this, other ViewControllers(BViewController, CViewController, DViewController) have to be dismissed. In the last case, my navigation flow should be like this: AViewController -> EViewController. Is there a way to do this ?
CodePudding user response:
First , create a function that helps you to push A to F
in Viewcontroller
A
func aToF(){
let fVC= self.storyboard?.instantiateViewController(withIdentifier: "your vc Id") as! FViewController
self.navigationController?.pushViewController(fVC, animated: false)
}
And where you go back to root and push F
call this :
let turnBack = self.navigationController?.viewControllers[0] as! AViewController
self.navigationController?.popToRootViewController(animated: false)
turnBack.aToF()
I do not recommend creating a new instance from an already memorized viewcontroller, but this is one of the easiest ways.
CodePudding user response:
do you want eviewcontroller back to Aviewcontroller, or you can push Aviewcontroller to Eviewcontroller
func pushFrom(vc: UIViewController.Type) {
guard let nv = self.navigationController else {
return
}
for controller in nv.viewControllers as Array {
if controller.isKind(of: vc.self) {
let eviewcontroller = Eviewcontroller()
controller.navigationController!.pushViewController(eviewcontroller,
animated: true)
break
}
}
}
Then
pushFrom(vc: AViewcontroller.self)
CodePudding user response:
You need to pop all the view controller till AViewcontroller
as
self.navigationController?.popToRootViewController(animated: true)
Then
self.navigationController?.pushViewController(EViewcontroller, animated: true)
Now it is AViewcontroller -> EViewcontroller
Another solution
self.navigationController?.pushViewController(EViewcontroller, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() 0.4) {
self.navigationController?.viewControllers.remove(at: 1) // Remove B
self.navigationController?.viewControllers.remove(at: 2) // Remove C
self.navigationController?.viewControllers.remove(at: 3) // Remove D
}
OR
Add this in EViewcontroller's viewDidAppear
self.navigationController?.viewControllers.remove(at: 1) // Remove B
self.navigationController?.viewControllers.remove(at: 2) // Remove C
self.navigationController?.viewControllers.remove(at: 3) // Remove D
CodePudding user response:
To replace the navigation stack of a view controller, use setViewControllers(_, animated:)
. If you pass in your existing AViewController
and a new EViewController
then your final navigation stack will be just those two.
There is no need to manually rebuild the stack you want by pushing and popping individual controllers.