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

时间:2015-10-09 08:54:20

标签: ios objective-c delegates

main storyboard image我有一个名为" Contacttableviewcontroller"和一个View Controller as" Detailviewcontroller"。我的View Controller中有2个文本字段,用于提供联系人姓名和号码。我有一个保存按钮。当我点击该按钮时,它应该在Table View Controller中显示它。我正在使用的概念是使用委托将信息从目的地传递到源。这是我的代码无法正常工作。

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

    }

3 个答案:

答案 0 :(得分:1)

首先,如果您已将行动方法-Save:附加到按钮上,则需要检查。您可以通过故事板或以编程方式附加它。要通过故事板进行操作,请为按钮指定一个名称,如saveButton(不是必须的),然后像往常一样通过ctrl拖动来附加它。

确保通过故事板正确附加所有IBOutlet。

enter image description here

enter image description here

P.S:我已用适当的命名约定更新了变量的名称。在命名变量时,您还应遵循驼峰惯例约定。

这是DetailViewController.h代码 -

#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

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

现在,如果你在你的动作方法中加入一个断点,你会看到,它正在被调用。 你可以看到一行额外的代码 -
[self.navigationController popToRootViewControllerAnimated:YES]; - 这样可以确保当您按下保存按钮时,它不仅会发送数据,还会返回给您TableView控制器以显示结果。

现在,您需要确保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)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 

现在,文件中有一些小的修改,但评论应该澄清目的。

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

#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

这可以帮助您解决所有问题。如果ContactTableViewController.m文件中有更改,我添加了一个或多个注释。我试图运行该应用程序,这是正常的。

答案 1 :(得分:0)

嘿,只需在您的视图中添加此行,然后执行Contacttableviewcontroller的加载方法。

private byte[] _content
public byte[] Content{
    get{
        return _content;
    }
    set{ //StackOverflowEx here
        _content=value;
    }
}

答案 2 :(得分:0)

试试这个

<强> 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;

和你做过的其他事情一样

**Detailviewcontroller.m**


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