0

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

    }
G.Abhisek
  • 1,034
  • 11
  • 44
  • additem method called or not? – Hardik Shekhat Oct 09 '15 at 09:01
  • where you have assigned detailviewcontroller.delegate = Contacttableviewcontroller's object? – johny kumar Oct 09 '15 at 09:01
  • sir i can't get you. can you please rectify my coding by giving yours – G.Abhisek Oct 09 '15 at 09:06
  • 1
    Assign delegate property in somewhere of DetailViewController And also call reloadtabledata method in additem method of Contacttableviewcontroller. – Alex Oct 09 '15 at 09:13
  • show your code of pushing from Contacttableviewcontroller's to detailviewcontroller. – johny kumar Oct 09 '15 at 09:14
  • possible Duplicates of : http://stackoverflow.com/questions/18566304/sending-data-from-one-viewcontroller-to-another – Piyush Oct 09 '15 at 09:19
  • sir, actually i am just simply wanting to pass the values from one class to other but that's the problem. i am new to xcode. so sir,can you please guide me in this situation like what i am missing in my coding and what are the necessary points that i should keep in my mind while handling these type of situation where i need to pass information from one view controller to another using delegates. – G.Abhisek Oct 09 '15 at 09:35
  • Please see the solution below, I provided a step by step solution which I tested and it seems to work according to your requirement. – Natasha Oct 09 '15 at 21:53

3 Answers3

1

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.

enter image description here

enter image description here

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.

Natasha
  • 6,651
  • 3
  • 36
  • 58
  • Detailviewcontroller *detailofcontact=[[Detailviewcontroller alloc]initwith:@"Detailviewcontroller" bundle:nil]]; Detailviewcontroller.delegate=self; can i do like this instead of doing your last part of coding – G.Abhisek Oct 09 '15 at 10:47
  • sorry, I didn't quite understood- which part you want to replace? You need to find out how you are initialising your destination View Controller and right after you initialise your DetailViewController is your Table View Controller, you need to tell it that it, itself is the implementer by assigning the controller's delegate property to self. – Natasha Oct 09 '15 at 11:03
  • I think, you can't do alloc]initWith for a view controller. You can either do Detailviewcontroller * detailofcontact = [[Detailviewcontroller alloc] init]; or you can do the way, I already showed. – Natasha Oct 09 '15 at 11:06
  • I updated my answer after you enquiry. I tried by myself and the above code should provide you exactly what we want. – Natasha Oct 09 '15 at 21:50
  • mam can you just explain me that whats going on in the prepare for segue method. Because as far as I know prepare for segue is used for passing values to from one view controller to another by recognizing the appropriate view controller using the "segue identifier". So how does it works here? – G.Abhisek Oct 12 '15 at 05:21
  • In the prepareForSegue method, you tell your controller, who is the destination controller. This line- DetailViewController *vc = [segue destinationViewController]; initialises a DetailViewController and set that as the destination. Now, before even going to your destination controller, you tell your origin view controller that it is the destination View Controller's delegate implementer. So, now your delegate method knows, where to look for the implementation. – Natasha Oct 12 '15 at 08:12
  • Mam can you please explain me that where should i write [self.tableview reload data] method in my program. I am really confused about the function and practical implementation areas of this method. Thank you again for all your previous responses. – G.Abhisek Oct 13 '15 at 05:19
  • reloadData method helps re-loading the table. So, if your data is changed, then you would probably want to reload the table. For example, in your case, when you are hitting the save button, your data is sent to the TableView Controller and the new data is appended in your mutable array. So, unless after you added the data in your array, you refresh the table, it may not reload and show that new data. so, you need to explicitly reload in such cases. – Natasha Oct 13 '15 at 08:12
  • Mam can you just visit this linlk and answer my question- http://stackoverflow.com/questions/33296610/questions-on-core-data – G.Abhisek Oct 23 '15 at 07:39
0

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

 DetailViewController *detailVc=[DetailViewController alloc]init];
 detailVc.delegate =self;
soumya
  • 3,801
  • 9
  • 35
  • 69
Akshay Agrawal
  • 217
  • 3
  • 12
  • its not working. nothing is showing after i click on the save button – G.Abhisek Oct 09 '15 at 10:32
  • Did you navigate to your contacttableviewcontroller after save method method is called in your detailviewcontroller – Akshay Agrawal Oct 09 '15 at 10:34
  • i am using a push segue so i can go back to the contacttableviewcontroller by clicking on the back button right. my only problem is that while i save its not been shown in tableviewcontroller. can you give your coding so that i can see what fault do i have – G.Abhisek Oct 09 '15 at 10:44
  • Just add a breakpoint on your - (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile method in contacttableviewcontroller and check whether this breakpoint hits when you press save button in detailviewcontroller. – Akshay Agrawal Oct 09 '15 at 10:47
  • Hey you did not call reload data method of table view inside the save method of contacttableviewcontroller. – Akshay Agrawal Oct 09 '15 at 10:51
  • First, make sure the action method is getting called. Then make sure, you have assigned the Table View controller as the delegator (one who is implementing the delegate method) of the View Controller. – Natasha Oct 09 '15 at 11:08
  • @natasha mam can you explain what do you mean by this or where should i particularly do this activity with reference to my coding which i have mentioned earlier in my question -> 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 like- – G.Abhisek Oct 09 '15 at 11:22
  • I can't see your entire code. That's why, I can't understand how you are going to the DetailViewcontroller from your Table View Controller. As you said, you want to send data from your destination to source using delegates, I am assuming, the DetailViewController is your destination. That means the TableViewController is your source, but how are you going to your destination from your source? Please share that code snippet. That way, I may probably give you more particular solution. – Natasha Oct 09 '15 at 12:22
  • @natasha - Mam, I have included an image of my main story board and thus you can get an overall idea of what I am trying to do? – G.Abhisek Oct 09 '15 at 12:50
  • Can you please post the code for the add method of your TableViewController? – Natasha Oct 09 '15 at 12:55
  • @natasha Mam,i have added the method like this--> - (void)additem:(NSString *)Name MOBILE:(NSString *)Mobile { self.contactname=Name; self.contactno=Mobile; self.contactnamearray=@[self.contactname]; self.contactnoarray=@[self.contactno]; } – G.Abhisek Oct 09 '15 at 13:28
  • Not the implementation of the delegate method, additem. From your storyboard's screen shot, I can see a button with "Add" title. I would like to see, the method for that button.. – Natasha Oct 09 '15 at 14:18
0

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];
}
Nischal Hada
  • 3,230
  • 3
  • 27
  • 57