iOS: How to “Refresh” a UIViewController after Pop

2020-07-27 16:50发布

问题:

In my app I'm using UINavigationController. I have a "parent" UIViewController and a "child" UIViewController running on the stack. The user can do some settings on the child that are later on suppose to affect the parent. I use NSUserDefaults to save and retrieve the data, and it seems to be working fine according to the NSLog.

What I'm not clear about is how am I supposed to "refresh" the data once I come back from the child.

Let me be more specific: In the child there is a "Back" button that does popViewControllerAnimated and then we go back to the parent. I want to re-run all the method I have in viewDidLoad so the parent view fields are set with the changes I got from the NSUserDefaults data.

  1. Where in the parent methods am I supposed to tell the view to "refresh"?
  2. How do I do this refresh action? should I call viewDidLoad again? I read about something called setNeedsDisplay, if that is the thing I should use, what is the syntax (is it "[self. view setNeedsDisplay]" or something else)?

Can anyone direct and elaborate?

回答1:

Take a look at NSNotification - thats an easy way to send updates from one part of your code to another is Apple’s built-in NSNotification system.

  1. If you have an update you want to send, you call postNotificationName. You just give it a unique string you make up (such as “com.razeware.imagegrabber.imageupdated”) and an object (such as the ImageInfo that just finished downloading its image).

  2. If you want to find out when this update happens, you call addObserver:selector:name:object. In our case the ImageListViewController will want to know when this happens so it can reload the appropriate table view cell. A good spot to put this is in viewDidLoad.

  3. Don’t forget to call removeObserver:name:object when the view gets unloaded. Otherwise, the notification system might try to call a method on an unloaded view (or worse an unallocated object), which would be a bad thing! via Ray Wenderlich blog



回答2:

You could use NSUserDefaultsDidChangeNotification as a trigger for refreshing the root view controller.



回答3:

You could also set your ViewController as a delegate to NavigationViewController

self.navigationController.delegate = self;

Then you will receive delegate calls in method:

- (void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated {
    NSLog(@"Did Show controller %@", viewController);
    // Return from child
    if ([viewController isKindOfClass:[SRPeopleViewController class]]) {
        [self loadData];
    }

}

Small drawback - or cost - of this solution is that you will receive more calls than you want, so filtering is necessary.