Home > Blockchain >  Unwanted behavior of setViewControllers in a UINavigationController
Unwanted behavior of setViewControllers in a UINavigationController

Time:09-07

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.

  • Related