Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refreshing data in a UIViewController after dismissing its presented modal view controller via delegate

I have the delegate working as the data is being passed from the modal to the presenting view controller. But the presenting view controller isn't showing the data it receives from the modal. I looked at other posts and they say to use the delegate/protocol method, but don't explain how/why the presenting VC refreshes. I'm assuming my delegate is setup incorrectly. Otherwise, what is the method to refresh the data? I've checked and the viewWillAppear and viewDidAppear doesn't get called.

SCCustomerDetailVC.h (Presenting VC)

#import "SCCustomersVC.h"

@interface SCCustomerDetailVC : UIViewController <SCCustomersVCDelegate>

@property (atomic, strong) SCCustomer *customer;
@property (strong, nonatomic) IBOutlet UIButton *changeCustomerButton;

- (IBAction)changeCustomerButtonPress:(UIButton *)sender;

@end

SCCustomerDetailVC.m (Presenting VC)

- (IBAction)changeCustomerButtonPress:(UIButton *)sender 
{    
    UINavigationController *customersNC = [self.storyboard instantiateViewControllerWithIdentifier:@"customersNC"];
    SCCustomersVC *customersVC = (SCCustomersVC *)customersNC.topViewController;
    customersVC.delegate = self;
    [self presentViewController:customersNC animated:YES completion:nil];
}

//Protocol methods
- (void)passCustomer:(SCCustomer *)customer
{
    self.customer = customer;

    //At this point, self.customer has the correct reference

    [self dismissViewControllerAnimated:YES completion:nil];
}

SCCustomersVC.h (Modal VC)

#import "SCCustomersVCDelegate.h"

@class SCCustomerDetailVC;

@interface SCCustomersVC : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>

@property (weak, nonatomic) id <SCCustomersVCDelegate> delegate;

@end

SCCustomersVC.m (Modal VC)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    SCCustomer *customer = [self customerAtIndexPath:indexPath];
    [self.delegate passCustomer:customer];
}

SCCustomersVCDelegate.h

@class SCCustomer;

@protocol SCCustomersVCDelegate <NSObject>
@optional

- (void)passCustomer:(SCCustomer *)customer;

@end
like image 444
abc123 Avatar asked Mar 18 '13 04:03

abc123


People also ask

How do I refresh ViewController after dismiss method is called?

So, viewWillAppear in ViewControllerA will not be called after dimissing ViewControllerB. If you don't want to change the modalPresentationStyle to fullScreen then you can use closures for passing data to ViewControllerA when you're dismissing ViewControllerB.

How can you reload a ViewController after dismissing a modally presented view controller in Swift?

Swift 5: You can access the presenting ViewController (presentingViewController) property and use it to reload the table view when the view will disappear. When you dismiss the SecondViewController, the tableview of the FirstViewController will reload. In my case, presentingViewController is SecondViewController.


2 Answers

I think you're nearly there. EDIT - just learned here that viewWillAppear behavior is different in iOS>5. You still want view will appear to update your view with your model state, since it needs to do that on initial presentation.

And it's fine to call it from either your modal vc or from within the delegate method. So add code to viewWillAppear that updates the view with the view controller's model state...

// SCCustomerDetailVC.m
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // making up an IBOutlet called someLabel
    // making up a model method (description) that returns a string representing your model
    self.someLabel.text = [self.customer description];
}

Then either from the presented vc or the delegate, call viewViewWillAppear:

- (void)passCustomer:(SCCustomer *)customer
{
    self.customer = customer;
    [self viewWillAppear:YES];
    [self dismissViewControllerAnimated:YES completion:^{}];
}
like image 59
danh Avatar answered Sep 17 '22 12:09

danh


You should reload your UI after setting the "customer"

- (void)passCustomer:(SCCustomer *)customer
{
    self.customer = customer;

    //At this point, self.customer has the correct reference

    [self dismissViewControllerAnimated:YES completion:^{
            // reload your UI here or call a method which will reload your ui
            // e.g. for tableView it will be [tableView reload];
        }];
}
like image 31
Evgeniy Gushchin Avatar answered Sep 17 '22 12:09

Evgeniy Gushchin