I have a simple VC:
class ViewController: UIViewController {
lazy var button = UIButton(frame: CGRect(x: view.frame.width/2-100, y: view.frame.height/2-25, width: 200, height: 50))
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
title = "ViewController"
view.addSubview(button)
button.configuration = .tinted()
button.configuration?.title = "Click me"
button.configuration?.baseBackgroundColor = .systemPink
button.configuration?.baseForegroundColor = .systemPink
button.addTarget(self, action: #selector(click), for: .touchUpInside)
}
And the function for the button:
@objc
func click() {
let newVC = ViewController()
newVC.title = "ViewController 2"
newVC.view.backgroundColor = .systemCyan
var copyVCS = self.navigationController!.viewControllers
print("\n-----Copied Stack------\n\(copyVCS)")
copyVCS = copyVCS.dropLast()
copyVCS.append(newVC)
print("\n-----Mutated Stack------\n\(copyVCS)")
self.navigationController!.setViewControllers(copyVCS, animated: true)
print("\n-----New Navigation Stack-----\n\(navigationController!.viewControllers)")
}
Basically, I am testing a bug I have in a larger app I'm working on.
The issue is where I am setting the new navigation stack by calling
self.navigationController?.setViewControllers(copyVCS, animated: true)
Seems like the new navigation stack isn't the same as the copyVCS
that I pass to the above method's argument.
The console after clicking the button:
-----Copied Stack------
[<VCBugReproduce.ViewController: 0x149d090f0>] // ✓
-----Mutated Stack------
[<VCBugReproduce.ViewController: 0x149f04440>] // ✓
-----New Navigation Stack-----
[<VCBugReproduce.ViewController: 0x149d090f0>, // ˟
<VCBugReproduce.ViewController: 0x149f04440>]
Is there a reason the new navigation stack isn't the same as the mutated stack? for some reason, the popped ViewController still appears in the navigation stack, but it appears now at the first index of the navigation stack array.
CodePudding user response:
The docs say:
If animations are enabled, this method decides which type of transition to perform based on whether the last item in the items array is already in the navigation stack. (either a push or a pop...)
Only one transition is performed, but when that transition finishes, the entire contents of the stack are replaced with the new view controllers.
Is it that you're reading the value of viewControllers before the animation transition has completed, and that is before the value has in fact changed to the 'after animation' value.