Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UINavigationController intercepting – popViewControllerAnimated:

So the the problem is that when someone touches the back button on the UINavigationControler, I would like to run some code to update the datasource.

The problem is that i cant seem to find the right delegate to do it. only these are available on the nav controller delegate, and i want the 'didfinishshowing' type method.

– navigationController:willShowViewController:animated:  optional method  
– navigationController:didShowViewController:animated:  optional method  

The next best place i thought was the nav bar but when i try that.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot manually set the delegate on a UINavigationBar managed by a controller

This makes sense retrospectively, as you don't want some hacker messing around with the internals of the nav controller and stopping it from working.

This must is a common problem, and i have missed something simple.

like image 769
Bluephlame Avatar asked Dec 08 '22 07:12

Bluephlame


2 Answers

Just so we're clear: view A is the starting point. User taps something and you slide right to view B. User taps the back button and you're going from B back to A and you want to do something as a result of the 'back' action.

There are three ways to do it (and on neither do you have to go near the navigationController -- these apply to the underlying viewControllers themselves):

  • As dmercredi suggests override viewWillAppear on view controller A so when you're heading back to it, it refreshes itself. Problem is that viewWillAppear is also called when A is called the very first time. So you'll have to set some sort of flag to distinguish between the first viewWillAppear and any subsequent ones when returning from B.

  • Override viewWillDisappear on view controller B and do your refreshing there. This will only get called when B is about to go away. If there's something on B that goes one level deeper or brings up a modal dialog on top, viewWillDisappear is going to get called so again you'll have to distinguish between the coming and the going.

  • Decouple the various views and use the delegate pattern. View controller A sets itself as a delegate of B and when B updates something it invokes the delegate method, so A is notified of the change and can update whatever it needs to. You can invoke the delegate method any time the user makes a change inside B or override viewWillDisappear and just do it one time on the way out.

like image 86
Ramin Avatar answered Dec 09 '22 20:12

Ramin


Add your refresh code to the viewWillAppear:(BOOL)animated method on the view controller that is about to be displayed. In your case, that is the view controller that's already on the navigation stack.

like image 42
dmercredi Avatar answered Dec 09 '22 20:12

dmercredi