简体   繁体   中英

How to pass message using delegates from one view controller to another using delegate?

main storyboard image I have one Table View Controller named "Contacttableviewcontroller" and one View Controller as"Detailviewcontroller". I have 2 text fields in my View Controller to give contact name and number. I have a button to save. When I click on that button, it should display it in Table View Controller. Concept I am using is passing information from destination to source using delegates. Here goes my code which is not working properly.

    Detailviewcontroller.h


    @protocol detailviewcontrollerdelegate<NSObject>
        - (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile;
    @end


    @interface DetaiViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UITextField *nametextfield;
    @property (weak, nonatomic) IBOutlet UITextField *mobiletextfield;
    - (IBAction)Save:(id)sender;

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

    Detailviewcontroller.m


    - (IBAction)Save:(id)sender {
        [self.delegate additem:self.nametextfield.text  MOBILE:self.mobiletextfield.text];
    }

Contacttableviewcontroller.h

@interface ContactTableViewController : UITableViewController<detailviewcontrollerdelegate>
@property(strong,nonatomic)NSString *contactname;
@property(strong,nonatomic)NSString *contactno;


-(void)reloadtabledata;



@property(strong,nonatomic)NSArray *contactnamearray;
@property(strong,nonatomic)NSArray *contactnoarray;
@end

    Contacttableviewcontroller.m



    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

        return 4;
    }
     - (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile
    {
        self.contactname=Name;
        self.contactno=Mobile;
        self.contactnamearray=@[self.contactname];
        self.contactnoarray=@[self.contactno];

    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellreuse" forIndexPath:indexPath];

        cell.textLabel.text=[_contactnamearray objectAtIndex:indexPath.row];
        cell.detailTextLabel.text=[_contactnoarray objectAtIndex:indexPath.row];

        return cell;

    }
    -(void)reloadtabledata
    {
        [self.tableView reloadData];

    }

Firstly, you need to check, if you have attached your action method, -Save: to your button or not. You can attach it through the storyboard or programatically. To do it through storyboard, give your button a name like saveButton(not compulsory) and then attach it by ctrl dragging as usual.

Make sure, you attach all the IBOutlets through storyboard properly.

在此处输入图片说明

在此处输入图片说明

PS: I have updated the variable's name with proper naming convention. You should also follow the camel case convention while naming your variables.

here is the DetailViewController.h code-

#import <UIKit/UIKit.h>

@protocol DetailViewControllerDelegate;

@interface DetailViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *nameTextField;
@property (weak, nonatomic) IBOutlet UITextField *mobileTextField;

@property(strong, nonatomic) IBOutlet UIButton *savebutton;

- (IBAction)Save:(id)sender;

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


@end


@protocol DetailViewControllerDelegate<NSObject>
- (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile;
@end

And DetailViewController.m -

 #import "DetailViewController.h"

    @interface DetailViewController ()

    @end

    @implementation DetailViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
    }

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }


   - (IBAction)Save:(id)sender {
         [self.delegate additem:self.nameTextField.text      MOBILE:self.mobileTextField.text];
         [self.navigationController popToRootViewControllerAnimated:YES];
   }

@end

Now, if you put a break point inside your action method, you will see, it is getting called. You can see an extra line of code-
[self.navigationController popToRootViewControllerAnimated:YES]; -this is making sure that when you press the save button, it not only sends the data, but also returns to you TableView Controller to show your results.

Now, you need to make sure that your DetailViewController knows who is going to implement its delegate. So, in your ContactTableViewController, wherever, you are initialising your DetailViewController, you have to assign its delegate to self.

So, after a little tweaks, the ContactTableViewController.h class looks like-

#import <UIKit/UIKit.h>
#import "DetailViewController.h"

@interface ContactTableViewController : UITableViewController<DetailViewControllerDelegate>

@property(strong,nonatomic)NSString *contactName;
@property(strong,nonatomic)NSString *contactNo;


-(void)reloadtabledata;


@property(strong,nonatomic)NSMutableArray *contactNameArray; //need to be mutable array, so that the data can keep appending
@property(strong,nonatomic)NSMutableArray *contactMobileNoArray; //same as above

@end 

Now, there are some small modifications in the file but, the comments should clarify the purpose.

So, the ContactTableViewController.m file looks like

#import "ContactTableViewController.h"

@interface ContactTableViewController ()

@end

@implementation ContactTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //Make sure you initialize the array before tryig to add any element

    self.contactNameArray =[[NSMutableArray alloc]init];
    self.contactMobileNoArray=[[NSMutableArray alloc]init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}


#pragma mark-
#pragma mark- TableView Datasource methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [self.contactNameArray count];  //you need to set the row count as the same as the array elements
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellreuse" forIndexPath:indexPath];

    cell.textLabel.text=[self.contactNameArray objectAtIndex:indexPath.row];
    cell.detailTextLabel.text=[self.contactMobileNoArray objectAtIndex:indexPath.row];

    return cell;

}

-(void)reloadtabledata
{
    [self.tableView reloadData];

}

#pragma mark- Segue method

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    [segue.destinationViewController setTitle:@"Add Details"];
    DetailViewController *vc = [segue destinationViewController];

    vc.delegate=self; // By this, you just told your TableViewController that it is responsible for the implementation of the DetailViewController's delegate
}

#pragma mark- DetailViewController's Delegate method

- (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile
{
    self.contactName=Name;
    self.contactNo=Mobile;
    [self.contactNameArray addObject:self.contactName];    //added the new entry
    [self.contactMobileNoArray addObject:self.contactNo];  //added the new entry

    [self.tableView reloadData]; //reload the table right after you updated the arrays
}

@end

This should help you with all your queries. If there is a change in the ContactTableViewController.m file, I added one or more comments. I tried to run the app and this is working properly.

Hey Just add this line in your view did load method of Contacttableviewcontroller.

 DetailViewController *detailVc=[DetailViewController alloc]init];
 detailVc.delegate =self;

Try this one

detailviewcontrollerdelegate

#import <Foundation/Foundation.h>

    @protocol detailviewcontrollerdelegate<NSObject>
        - (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile;
    @end

Detailviewcontroller.h

#import <UIKit/UIKit.h>
#import "detailviewcontrollerdelegate.h"
    @interface DetaiViewController : UIViewController{
    id< detailviewcontrollerdelegate > delegate;
     }
    @property (nonatomic, assign) id< detailviewcontrollerdelegate > delegate;
    @property (weak, nonatomic) IBOutlet UITextField *nametextfield;
    @property (weak, nonatomic) IBOutlet UITextField *mobiletextfield;
    - (IBAction)Save:(id)sender;

and other as u have done make it same

**Detailviewcontroller.m**


- (IBAction)Save:(id)sender {
    [self.delegate additem:self.nametextfield.text  MOBILE:self.mobiletextfield.text];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM