10

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,095
  • 13
  • 148
  • 192
Mocha
  • 1,782
  • 10
  • 27

1 Answers1

24

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
  • 307,833
  • 40
  • 508
  • 550
  • 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
  • 1
    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