2

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.

normal viewDidAppear callstack

viewDidAppear after enterBackground callstack

zmc1213
  • 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
  • 1
    Please 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 Answers6

1

If you can repro by:

  1. 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)
  2. 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

Community
  • 1
  • 1
Ling Li
  • 11
  • 2
0

Is the viewcontroller which you pushed into the view hierarchy overwrite the viewWillAppear/viewDidAppear accidently without calling [super viewWillAppear/viewDidAppear:animated]?

0

You're probably accidentally calling [super viewDidLoad] inside your viewWillAppear method

Alon Shacham
  • 299
  • 3
  • 6
0

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.

vrwim
  • 13,020
  • 13
  • 63
  • 118
0

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
}
mourodrigo
  • 2,232
  • 28
  • 18
-1

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