如何使用委托将消息从一个视图控制器传递到另一个使用委托的视图控制器? [英] How to pass message using delegates from one view controller to another using delegate?

查看:58
本文介绍了如何使用委托将消息从一个视图控制器传递到另一个使用委托的视图控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





PS



这是 DetailViewController.h 代码-

  #import< UIKit / UIKit.h> 

@ protocol DetailViewControllerDelegate;

@interface DetailViewController:UIViewController

@property(弱,非原子)IBOutlet UITextField * nameTextField;
@property(弱,非原子)IBOutlet UITextField * mobileTextField;

@属性(强,非原子)IBOutlet UIButton *保存按钮;

-(IBAction)保存:(id)发件人;

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


@end


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

DetailViewController.m -

  #import DetailViewController.h 

@interface DetailViewController()

@end

@implementation DetailViewController

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

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


-(IBAction)保存:(id)发件人{
[self.delegate additem:self.nameTextField.text MOBILE:self.mobileTextField.text ];
[self.navigationController popToRootViewControllerAnimated:YES];
}

@end

现在,如果您将动作方法中的断点,您会看到它正在被调用。
您可以看到一行额外的代码-

[self.navigationController popToRootViewControllerAnimated:YES];
-确保按下保存按钮时,它不仅会发送数据,还会返回给TableView Controller显示结果。



现在,您需要确保您的DetailViewController知道谁将实现其委托。因此,在ContactTableViewController中的任何地方,无论您要初始化DetailViewController,都必须将其委托分配给self。



因此,经过一些调整后, ContactTableViewController.h 类看起来像-

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

@interface ContactTableViewController:UITableViewController< DetailViewControllerDelegate>

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


-(void)重新加载表格数据; @ b

$ b @property(strong,nonatomic)NSMutableArray * contactNameArray; //需要是可变数组,以便数据可以继续追加
@property(strong,nonatomic)NSMutableArray * contactMobileNoArray; //与上述

@end

相同,现在有些小



因此, ContactTableViewController.m 文件看起来像

  #import ContactTableViewController.h 

@interface ContactTableViewController()

@end

@implementation ContactTableViewController

-(void)viewDidLoad {
[super viewDidLoad];

//确保在tryig添加任何元素之前初始化数组

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

-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];

}


#pragma标记-
#pragma标记-TableView数据源方法

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

返回1;
}

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

return [self.contactNameArray count]; //您需要将行数设置为与数组元素相同
}


-(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];

返回单元格;

}

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

}

#pragma标记-Segue方法

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

[segue.destinationViewController setTitle:@添加详细信息];
DetailViewController * vc = [segue destinationViewController];

vc.delegate = self; //通过此操作,您刚刚告诉TableViewController它负责执行DetailViewController的委托
}

#pragma mark- DetailViewController的Delegate方法

- (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile
{
self.contactName = Name;
self.contactNo =移动电话;
[self.contactNameArray addObject:self.contactName]; //添加了新条目
[self.contactMobileNoArray addObject:self.contactNo]; //添加了新条目

[self.tableView reloadData]; //在更新数组
}

@end


$ b之后立即重新加载表$ b

这应该可以帮助您解决所有查询。如果ContactTableViewController.m文件发生更改,我添加了一个或多个注释。我尝试运行该应用程序,并且该应用程序正常运行。


main storyboard imageI 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.

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.

这篇关于如何使用委托将消息从一个视图控制器传递到另一个使用委托的视图控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆