Search code examples
iosobjective-cuitabbarcontrollerdelegation

Custom delegation to pass data between tab bar view in iOS not working


I am facing a problem related to delegation.I have 2 tabView. In first tabview i have 2 textfield and a button(to trigger the delegate method) and in the second tabview i have 2 label to display the content of textfield in the first tabview.Whats wrong with my code???

For first tabviewA the .h file

#import <UIKit/UIKit.h>
@class ViewControllerA;
@protocol ViewControllerADelegate <NSObject>
-(void)sayHello:(ViewControllerA*)viewController;
@end
@interface ViewControllerA : UIViewController<UITextFieldDelegate>
@property (nonatomic,strong)IBOutlet UITextField *textFieldFirst;
@property (nonatomic,strong)IBOutlet UITextField *textFieldSecond;
@property (nonatomic,strong)id<ViewControllerADelegate>delegate;
-(IBAction)next:(id)sender;
@end

and the .m file

#import "ViewControllerA.h"
@interface ViewControllerA ()
@end
@implementation ViewControllerA
@synthesize textFieldFirst=_textFieldFirst;
@synthesize textFieldSecond=_textFieldSecond;
@synthesize delegate=_delegate;
- (void)viewDidLoad
{
    [super viewDidLoad];
    _textFieldFirst.delegate=self;
    _textFieldSecond.delegate=self;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return NO;
}
-(IBAction)next:(id)sender
{
    [self.delegate sayHello:self];
}

@end

And for the second tabbarViewB the .h file

#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
@interface ViewControllerB : UIViewController<ViewControllerADelegate>
@property (nonatomic,strong)IBOutlet UILabel *labelFirst;
@property (nonatomic,strong)IBOutlet UILabel *labelSecond;

@end

and the .m file

#import "ViewControllerB.h"

@interface ViewControllerB ()

@end

@implementation ViewControllerB

@synthesize labelFirst=_labelFirst;
@synthesize labelSecond=_labelSecond;

- (void)viewDidLoad
{
    [super viewDidLoad];

    ViewControllerA *viewControllerA=[self.tabBarController.viewControllers objectAtIndex:0];

    viewControllerA.delegate=self;
    // Do any additional setup after loading the view.
}
-(void)sayHello:(ViewControllerA *)viewController
{
    _labelFirst.text=viewController.textFieldFirst.text;
    _labelSecond.text=viewController.textFieldSecond.text;
}

@end

N.B: I have tried tabView B to tabview A with the same process and that worked fine. The reverse (i.e from A to B)is not working at all.Thanks


Solution

  • ViewControllerB sets itself as the delegate in its viewDidLoad method. This method is called as soon as the View Controller has loaded the view it manages (into its view property). That view is loaded only when someone tries to access the view controller's view property for the first time. See here. There's a good chance that ViewControllerB's view has not been loaded yet, so the viewDidLoad method has not been called yet.

    If you override the awakeFromNib method like so:

    (void) awakeFromNib {
        [super awakeFromNib];
    
        ViewControllerA *viewControllerA=[self.tabBarController.viewControllers
                                          objectAtIndex:0];
        viewControllerA.delegate = self;
    }
    

    it should work, since that method will be called when the view controller is initialized.