26

Say I have UIViewController A and B. User navigates from A to B with a push segue. Than user presses back button and comes to A.

Now viewWillAppear of A is called. Can I know in the code here that I came from back button (navigationController popTo...) and not by another way? And without writing special code in the B view controller.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
adsurbum
  • 3,107
  • 3
  • 22
  • 27
  • 4
    possible duplicate of [Determine if view that appears was pushed or came from back button in navigation bar](http://stackoverflow.com/questions/20849171/determine-if-view-that-appears-was-pushed-or-came-from-back-button-in-navigation) – rmaddy Jan 09 '14 at 03:28

3 Answers3

32

hm, maybe you can use self.isMovingToParentViewController in viewWillAppear, see docs, if it is NO then it means the current view controller is already on the navigation stack.

falsecrypt
  • 1,536
  • 14
  • 11
14

I like to do the following in view controller A:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if (_popping) {
        _popping = false;
        NSLog(@"BECAUSE OF POPPING");
    } else {
        NSLog(@"APPEARING ANOTHER WAY");
    }

    //keep stack size updated
    _stackSize = self.navigationController.viewControllers.count;

    ....
}
- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    _popping = self.navigationController.viewControllers.count > _stackSize;

    ....
}

What you are doing is keeping track of whether your view controller (A) is disappearing because a view controller (B) is being pushed or for another reason. Then (if you did not modify the child view controller order) it should accurately tell you if (A) is appearing because of a pop on the navigation controller.

gwest7
  • 1,556
  • 19
  • 26
  • This will result in unexpected behavior if view controller A gets popped, retained, and push back onto the stack. – Ruiz Jun 15 '20 at 19:24
4

Add a BOOL property to UIViewController A:

@property (nonatomic) BOOL alreadyAppeared;

Then in your viewWillAppear: method, add:

if (!self.alreadyAppeared) {
    self.alreadyAppeared = YES;
    // Do here the stuff you wanted to do on first appear
}
Gavin
  • 8,204
  • 3
  • 32
  • 42