且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用委托将消息从一个视图控制器传递到另一个使用委托的视图控制器?

更新时间:2023-11-27 18:45:22

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.

P.S: 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.