In my app, sometimes pushViewController fails for no reason and what happens is very weird. The navigationBar and navigationItem change but the ViewController
is not pushed. Then I can tap nothing on the screen. I find that viewWillAppear
is called but viewDidAppear
isn't called. I push the home button of iPhone to enter background. After entering foreground again, the ViewController
is pushed and viewDidAppear
is called. I don't know why and when it happens.

- 41
- 4
-
Please overwrite `didRecieveMemoryWarning` and check if this method gets invoked – Saheb Roy Dec 18 '15 at 09:59
-
And please check your pushedFromView reference is still retained ? – Gihan Dec 18 '15 at 10:04
-
Also check if you are calling the same methods on super class. Like `[super viewWillAppear]` and `[super viewDidAppear]` in the respective functions. – Vishal Dec 18 '15 at 10:07
-
Are you doing anything in your `viewWillAppear`, `viewWillLayoutSubviews`, `viewDidLayoutSubviews`, or `updateViewContraints` (or any of the methods they call) that would block, loop forever, or the like? If you break in the debugger at that point, what does the call stack look like? – jcaron Dec 18 '15 at 10:58
-
`didRecieveMemoryWarning` doesn't get invoked. PushedFromView is still retained. The super class of viewController is `UIViewController`. – zmc1213 Dec 21 '15 at 09:39
-
@jcaron I set navigationBar tintColor in `viewWillAppear`. – zmc1213 Dec 21 '15 at 09:40
-
Please provide all relevant code, you're obviously doing something out of the ordinary. – jcaron Dec 21 '15 at 10:13
-
@SahebRoy didRecieveMemoryWarning doesn't get invoked. – zmc1213 Dec 21 '15 at 11:41
-
@Gihan PushedFromView is still retained. – zmc1213 Dec 21 '15 at 11:42
-
@Vishal The super class of viewController is UIViewController. – zmc1213 Dec 21 '15 at 11:42
-
@jcaron `- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController.navigationBar setHidden:NO]; _navigationBarConfig = config; for (UIView * subView in self.navigationController.navigationBar.subviews) if ([subView isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")]) { subView.alpha = config.hide?(config.alpha):1; } }` – zmc1213 Dec 22 '15 at 02:41
-
1Please update your question to add the code there rather than put it in a comment, it'll be much easier to read... – jcaron Dec 22 '15 at 08:19
-
Also, how do you know `viewDidAppear` isn't called? Breakpoint? Logs? Anything in `viewDidLayoutSubviews`, `updateViewContraints`? As already requested, if you break in the debugger at that point, what does the call stack look like? – jcaron Dec 22 '15 at 08:21
-
@jcaron I cleaned my code. There's nothing but `[self.navigationController.navigationBar setTitleTextAttributes:attributes]` in `viewWillAppear`. And I just `setFrame` of some subviews in `viewWillLayoutSubviews`. I do nothing in `viewDidLayoutSubviews ` and `updateViewContraints `. – zmc1213 Dec 23 '15 at 03:32
-
@jcaron I uploaded the picture of call stack. Every time `viewDidAppear` is called when the app enter background. And the call stack look like what the picture shows. Then the vc can be pushed when the app enter foreground again. – zmc1213 Dec 23 '15 at 03:36
6 Answers
If you can repro by:
- Try using the left edge pop gesture when there are no view controllers below it (i.e on root view controllers, your VC-Home controller)
- Try clicking on any UI elements after this.
Then Disable interactivePopGestureRecognizer when current viewController is the firstVC in navigation controller.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
reference: iOS App Freezes on PushViewController
Is the viewcontroller which you pushed into the view hierarchy overwrite the viewWillAppear/viewDidAppear accidently without calling [super viewWillAppear/viewDidAppear:animated]?
-
No. Every view controller called [super viewWillAppear/viewDidAppear:animated]. – zmc1213 Mar 14 '16 at 09:19
You're probably accidentally calling [super viewDidLoad] inside your viewWillAppear method

- 299
- 3
- 6
For anyone having the same issue as me: Check all your custom views to see if you're not having an infinite loop of layoutSubviews
. This is on of the things that happens in between a viewWillAppear
and a viewDidAppear
.

- 13,020
- 13
- 63
- 118
In my implementation I had a custom Tab bar controller and fore some reason viewDid Appear was empty, putting super calling solved it.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) //was missing this line
}

- 2,232
- 28
- 18
You know,if you overwrite navigationController.interactivePopGestureRecognizer.delegate and not restore it appropriately, this bug will appear,too