Navigation Controller PushViewController no longer calls ViewDidAppear/will

Hello,


Switching from iOS 12 to 13 caused that our views no longer function correctly. This is due that when NavigationController.PushViewController is called, it no longer calls ViewWill/DidAppear and their opposite Will/DidDisappear. I have read the iOS 13 release notes and saw the video and everyhing that has been mentioned regarding these events is directed at presentation of card-like modal views, which has nothing to do with the PushViewController function. In iOS 12 the PushViewController would navigate to a new ViewController and therefrom I could click on the default back button to navigate back to the previous one and it called the relevant lifecycle events. That is no longer possible with iOS 13.


The way our Views are constructed are quite old fashioned. We use XIB files to construct our Views and furthermore, this is done programmatically and the language used is Objective-C.


Most of our views are based on UIViewControllers, UITables and UITableViewController.


Now one thing I do know is that UITableViewController, through the use of ViewDidAppear/will, will call ReloadData to correctly set up the table, but since using PushViewController no longer calls these events, the layout will be broken.


It could possibly something that we missed or havent understood about the framework, but I have written this after searching through countless websites about someone with a similar issue, but to no avail.


An example of what happens can be seen below:



What I expect it to call is


ViewDidLoad --> ViewWillAppear --> ViewDidAppear


and when leaving the View it will call these:


ViewWillDisappear --> ViewDidDisappear --> ViewDidUnload(deprecated)



And no other viewController lifecycles except for ViewDidLoad is called.

This causes my view to look completely wrong.



For some reason the two images i pasted in here arent visible.

Accepted Reply

If I remember well, I had the problem with a navController as well.


I had to declare the navController as fullScreen, as well as the rootView (a TableViewController) and its linked views via push segues (so similar if I understand to your case).


The fullScreen does not draw as such in IB on the RootView, but works well on device or even simulator.


So, give it a try by forcing to fullScreen in viewDidload for the pushed view.


Question: do you declare in IB or in code ?

Replies

A possible reason is the default display mode a a view. It used to be fullscreen, it is now "automatic", which is why you see a small fraction of the calling veiw at top ; view does not disappear ; when you return, view has not to aappear.


Try to change (in viewDidLoad):

self.modalPresentationStyle = .fullScreen          // where self is the VC of course


Or do it in IB.

I get where you are coming from, but that is exclusively for when you use PresentViewController on a navigation Controller, which is used to display a Modal. What we use is the PushViewController method on NavigationController, and that is not a modal and therefore is per default in fullscreen. Which is why im confused as to why the ViewDidAppear/will isnt getting called, since its a different way to navigate.

If I remember well, I had the problem with a navController as well.


I had to declare the navController as fullScreen, as well as the rootView (a TableViewController) and its linked views via push segues (so similar if I understand to your case).


The fullScreen does not draw as such in IB on the RootView, but works well on device or even simulator.


So, give it a try by forcing to fullScreen in viewDidload for the pushed view.


Question: do you declare in IB or in code ?

Sorry for the late answer.


You were right. I just had to force it to full screen in ViewDidLoad. I had tried all possible combinations except for this, and thus I thought else was wrong. Now it works perfectly as it did before. Thank you for your time and answers. They have been helpful. I will mark your answer as the correct one.


I declare my navigation in code, if that is what you are asking about.

Hey there, I'm having the same issue but I'm not sure what you mean by forcing or declare navController as full screen. You mean via it's frame? Are you talking about modal presentation style? I'm confused by why this is happening for me. I'm also not presenting modally but on iOS 13 the viewWillAppear isn't called.

If you define the navController in IB, you can see a Presentation Field in Attributes inspector.

It is automatic by default, change it to fullScreen.


And do the same for the controllers inside the navigation.


Hopes that's clear.

Hi, I am having exactly the same issue as you were using IOS 13.3 and Xcode 11.3. I'm using code to create navigationcontroller and XIB.

I am using pushViewController


I entered


<self.modalPresentationStyle=UIModalPresentationFullScreen;>


within each VC viewDidLoad


The ViewWillAppear still does not call when I popRootViewController or pop back to a previous VC.


I am creating the naviagtioncontroller as the rootcontroller within AppDelegate.


Can you provide me what you did to resolve this?

The problem is explained in viewWillAppear doc:

This method is called before the view controller'€™s view is about to be added to a view hierarchy and before any animations are configured for showing the view.


As the view is aalready in view hiearchy, it is not called.


I would try a few approaches (did not fully test):

- move the code you need from viewWillAppear to viewDidDisappear of the controller you leave (if possible)

- send a notification from the view you leave (in viewWillDisparrear) to the view that will appear and move the code in the action for this notification

- Try to set fullscreen in IB and not in code (worked for me)

The navController was not created in IB.

I used <self.modalPresentationStyle=UIModalPresentationFullScreen;> within every VC wiewDidLoad as stated above.


I had someone send me a test project with three pushed VCs and when he used popPopViewController:animated to return to previous VC it calls viewWillAppear on that VC. This is how my app worked before IOS 13 update. BTW, he used storyboard and the NavController was in the IB and ptresentation was set to automatic, which is even more confusing.


If I launch an actual device instead of the simulator (and that device has IOS 13.3.1), it works perfectly and just as the simulators under previous versions worked. So I'm really at a loss. Not sure how dknudsen above found this as a solutiuon because he sounds exactly like me.


I am implementing an AppDelegate for the views. I made that NavController fullscreen and the views related to that fullscreen with the AppDelegate but not sure if the order has something to do with it.


Do you have an example of that notification method you suggested. HAve never used notification

Just to add my 2 cents, I have the same issue now in iOS 13 only with an app that was originally built with NIBs and with a coded NavController. Have tried eveything above including starting with a Storyboard for the LaunchScreen - #1 because Apple is making us and #2 just to see if it would force the proper behavior. It did not, so very frustrating to have something written to spec and working properly since iOS 3 just suddenly fail on a routine basis.


Soooo...I got to thinking instead of banging my head against the wall and fruitlessly tweaking all these FullScreen settings, why not just do the job myself if Apple's dropping the ball.


So, I just subclassed UINavigationController and overrode pushViewController so that I call 'viewWillAppear' and 'viewDidLoad' my **** self. And...it works!...basically.


Because the lifecycle views sometimes get called in response to pushing/popping, they can get called redundantly. This creates a noticeable performance hit and UI stutter, but at least 2 calls is better than 0 calls.


Next step is adding some kind of flag to see if the methods have been properly called and then conditionally call them as needed.


Open to any ideas or suggestions around this (especially from Apple saying they've fixed things).