iosobjective-cuiviewcontrolleruipresentingcontroller

Get reference to View ControllerA from ViewControllerB to change property


I have a custom ViewController A with an instance variable or property that I want to change from a second custom view controller launched by a navigation controller for ViewControllerA.

Here is my code to launch ViewController B from within A

In FirstCustomVC:

- (void) launchSecondVC {
    UIStoryboard *storyBoard = self.storyboard;
  
    CustomVC * myVC =
    [storyBoard instantiateViewControllerWithIdentifier:@"myvc"];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: CustomVC;
    [self presentViewController:nav animated:YES completion:nil];
}  

After ViewController B is launched and the user does something, I want to dismiss ViewController B and enable a button back in ViewController A. I can dismiss VCB but I am having trouble grabbing a reference to A in order to enable the button.

The following successfully dismisses VCB. However, the presenting ViewController is a navigation controller and does not have the property I need so it crashes if I try to access the property.

[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];//dismisses successfully
self.presentingViewController.myButton.enabled = YES;//crashes as the property is on the VC, not the nav

I've tried various methods to get the topViewController but can only get a generic UIViewController rather than the custom one with the button property.

How can I grab a reference to the custom VC that is actually displayed on the screen?


Solution

  • The best option is using delegation. It prevents tight coupling between controllers and ensures clean, modular, and reusable code.

    CustomVC.h:

    @protocol CustomVCDelegate <NSObject>
    - (void)customVCDidFinish:(BOOL)enableButton;
    @end
    
    
    @interface CustomVC : UIViewController
    @property (nonatomic, weak) id<CustomVCDelegate> delegate;
    @end
    

    FirstCustomVC.h:

    #import "CustomVC.h"
    
    @interface FirstCustomVC : UIViewController <CustomVCDelegate>
    @property (weak, nonatomic) IBOutlet UIButton *myButton;
    @end
    

    FirstCustomVC.m:

    - (void)customVCDidFinish:(BOOL)enableButton {
        self.myButton.enabled = enableButton;
    }
    
    - (void)launchSecondVC {
        UIStoryboard *storyBoard = self.storyboard;
        CustomVC *myVC = [storyBoard instantiateViewControllerWithIdentifier:@"myvc"];
        
        myVC.delegate = self; // Назначаем делегата
        
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myVC];
        [self presentViewController:nav animated:YES completion:nil];
    }
    
    

    CustomVC.m:

    - (void)dismissAndSendData {
        if ([self.delegate respondsToSelector:@selector(customVCDidFinish:)]) {
            [self.delegate customVCDidFinish:YES]; // Сообщаем делегату включить кнопку
        }
        
        [self dismissViewControllerAnimated:YES completion:nil]; // Закрываем ViewController B
    }