45

I have a View controller displaying some information (not table views).

I have an update call to a remote server which fills my data base. I would like to completely reload my ViewController after the update call is done.

What should I do?

Tiago Veloso
  • 8,513
  • 17
  • 64
  • 85
  • 2
    How do you currently update your data - I am assuming you are using viewDidAppear? – Till Mar 13 '12 at 14:53
  • Can't you use either the NotificationCenter or a protocol to inform your ViewController that the update has ended? – Khal Mar 13 '12 at 14:55
  • @Khal I've never used Notification center, could you point me to a tutorial or guide? @Till I use `viewWill/DidAppear` as well as `loadView` and `viewDidLoad`. – Tiago Veloso Mar 13 '12 at 15:06
  • Here is a tutorial on NSNotificationCenter : http://blog.shoguniphicus.com/2011/03/07/objective-c-nsnotification-key-value-observing/ But just for your own record, I would rather use a protocol to inform your ViewController that the update has ended ;) – Khal Mar 14 '12 at 12:14

10 Answers10

28

If you know your database has been updated and you want to just refresh your ViewController (which was my case). I didn't find another solution but what I did was when my database updated, I called:

[self viewDidLoad];

again, and it worked. Remember if you override other viewWillAppear or loadView then call them too in same order. like.

[self viewDidLoad]; [self viewWillAppear:YES];

I think there should be a more specific solution like refresh button in browser.

buczek
  • 2,011
  • 7
  • 29
  • 40
Moaz Saeed
  • 1,006
  • 3
  • 10
  • 23
  • 1
    Never ever call lifecycle methods !!! use [self.view setNeedsDisplay] or [self.view setNeedsLayout] for example – Marc Aug 14 '19 at 20:27
17

If you want to reload a ViewController initially loaded from a XIB, you can use the next UIViewController extension:

extension UIViewController {
    func reloadViewFromNib() {
        let parent = view.superview
        view.removeFromSuperview()
        view = nil
        parent?.addSubview(view) // This line causes the view to be reloaded 
    }
}
juancazalla
  • 1,050
  • 11
  • 17
  • Hi @juancazalla, I tried the above snippet for refreshing my view controller, so Its again calling ```viewdidload()``` method from controller. how to escape this ```view did load``` call and refresh my view. – Umesh Verma May 14 '20 at 06:43
9

You really don't need to do:

[self.view setNeedsDisplay];

Honestly, I think it's "let's hope for the best" type of solution, in this case. There are several approaches to update your UIViews:

  1. KVO
  2. Notifications
  3. Delegation

Each one has is pros and cons. Depending of what you are updating and what kind of "connection" you have between your business layer (the server connectivity) and the UIViewController, I can recommend one that would suit your needs.

Rui Peres
  • 25,741
  • 9
  • 87
  • 137
8

Try this, You have to call both methods to reload view, as this one works for me,

-Objective-C

[self viewDidLoad]; 
[self viewWillAppear:YES];

-Swift

self.viewDidLoad()
self.viewWillAppear(true)
Patel Jigar
  • 2,141
  • 1
  • 23
  • 30
2

Direct to your ViewController again. in my situation [self.view setNeedsDisplay]; and [self viewDidLoad]; [self viewWillAppear:YES];does not work, but the method below worked.

In objective C

UIStoryboard *MyStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil ];
UIViewController *vc = [MyStoryboard instantiateViewControllerWithIdentifier:@"ViewControllerStoryBoardID"];
[self presentViewController:vc animated:YES completion:nil];

Swift:

let secondViewController = self.storyboard!.instantiateViewControllerWithIdentifier("ViewControllerStoryBoardID")   
self.presentViewController(secondViewController, animated: true, completion: nil)
  • In my view, the best way to "reload the ViewController" is simply to remove the object from memory and create an entirely new one (as is done above). This also removes viewModels, etc. from memory that were instantiated in the VC (assuming no circular reference issues). Just switching out views doesn't really cut it, and doesn't account for logic running outside the VC that's being refreshed. – Swifty McSwifterton Sep 07 '18 at 21:35
1

It is not advised to call ViewDidLoad or ViewWillAppear by yourself.

In the ViewDidLoad include a loadData() function to prepare the data. This is executed in the initial run.

When you want to reload, call loadData() again to get the data from model. In a tableView call reloadData() or in a regular view setNeedsDisplay().

Vincent
  • 4,342
  • 1
  • 38
  • 37
1

Update the data ... change button titles..whatever stuff you have to update..

then just call

[self.view setNeedsDisplay];
Shubhank
  • 21,721
  • 8
  • 65
  • 83
  • 2
    I have to reload a couple of entries from the Database. I don't think that redrawing the views is the way to go here. – Tiago Veloso Mar 13 '12 at 20:26
0

Reinitialise the view controller

YourViewController *vc = [[YourViewController alloc] initWithNibName:@"YourViewControllerIpad" bundle:nil];
[self.navigationController vc animated:NO];
Muhammad Aamir Ali
  • 20,419
  • 10
  • 66
  • 57
  • this is old-style. Modern projects with storyboard most likely won't use XIB; use Storyboard instead. – Raptor Jun 06 '14 at 03:06
-1

For UIViewController just load your view again -

func rightButtonAction() {
        if isEditProfile {
           print("Submit Clicked, Call Update profile API")
            isEditProfile = false
            self.viewWillAppear(true)
        } else {
            print("Edit Clicked, Call Edit profile API")
            isEditProfile = true
            self.viewWillAppear(true)
        }
    }

I am loading my view controller on profile edit and view profile. According to the Bool value isEditProfile updating the view in viewWillAppear method.

iknow
  • 8,358
  • 12
  • 41
  • 68
-6

You Must use

-(void)viewWillAppear:(BOOL)animated

and set your entries like you want...

Hiren
  • 12,720
  • 7
  • 52
  • 72
plop
  • 11
  • This might be a valid hint for for when to *send* the request to a web service to load data, but it doesn't answer how to handle the web service response asynchronously to update the view. – Mike Mertsock Oct 08 '13 at 13:52