15

I am popping a view controller deep within a navigation stack. Is it possible to detect if the view controller is being shown from a push or a pop?

nav stack:

[A] -> [B] -> [C] -> [D] -> [E]

[E] pops to [B]

nav stack:

[A]  -> [B] // Possible to detect if B appears from a pop?
jscs
  • 63,694
  • 13
  • 151
  • 195
Mocha
  • 2,035
  • 12
  • 29

1 Answers1

30

In view controller B, implement either viewWillAppear or viewDidAppear. In there, use isMovingToParent and isBeingPresented to see under what conditions it is appearing:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if !isBeingPresented && !isMovingToParent {
        // this view controller is becoming visible because something that was covering it has been dismissed or popped
    }
}

Below is a more general use of these properties that people may find handy:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if isMovingToParent {
        // this view controller is becoming visible because it was just push onto a navigation controller or some other container view controller
    } else if isBeingPresented {
        // this view controller is becoming visible because it is being presented from another view controller
    } else if view.window == nil {
        // this view controller is becoming visible for the first time as the window's root view controller
    } else {
        // this view controller is becoming visible because something that was covering it has been dismissed or popped
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Thanks! I have a question.. isMovingToParent = true when it is pushed to the navstack because it is "moving to the nav stack" ? – Mocha Jan 15 '19 at 21:44
  • @Mocha That is correct. `isMovingToParent` will be `true` when you go push B onto A. – rmaddy Jan 15 '19 at 21:45
  • 2
    A doubt: is it not `isBeingPresented` always `false` in this case? I mean, it can be omitted in this scenario, right?... Or if I am wrong, when it could be this variable `true`? – Ángel Téllez Jan 15 '19 at 21:50
  • @ÁngelTéllez Yes, in this specific case it should always be false and omitted. I showed for the sake of completion. – rmaddy Jan 15 '19 at 21:52
  • 3
    Also this is not the case for root tab bar controllers. The condition will be true even when you switch tabs. – Aleš Oskar Kocur Dec 09 '21 at 08:13