How to populate an array from detailViewController and return to masterViewController in iOS?

149 Views Asked by At

I have a tableView from which I navigate to a 'viewController' ie PassengerInfoViewController in which I have a form.I fill up the form , make a dictionary out of it and add it to a NSMutableArray.

So when I am going back to the tableView' I would like to pass this array and then reload thetableView` with the filled array.

So here's what I am doing : -

  //navigate to the form
  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

  PassengerInfoViewController *pivc = [self.storyboard instantiateViewControllerWithIdentifier:@"PassengerInfoViewController"];
  [self.navigationController pushViewController:pivc animated:YES];

}

 //After filling up the form 

 -(void)goBackToPassengerDetails:(UIButton*)sender{

   NSString *title = self.titleTextField.text;
   NSString *fname = self.firstNameTextField.text;
   NSString *lname =self.lastNameTextField.text;
   NSString *ageStr = self.ageTextField.text;

   NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
   [dict setValue:title forKey:@"title"];
   [dict setValue:fname forKey:@"firstName"];
   [dict setValue:lname forKey:@"lastName"];
   [dict setValue:ageStr forKey:@"age"];
   Passenger *passengerObj = [Passenger sharedInstance]; //Singleton

   [passengerObj.passengerDetailArray addObject:dict];

    PassengerDetailsViewController *pdc = [self.storyboard instantiateViewControllerWithIdentifier:@"PassengerDetailsViewController"];
[pdc getPassengerinfo:passengerObj.passengerDetailArray];
[self.navigationController popViewControllerAnimated:YES];

Once I navigate back I reload the table view.However celForRow method doesn't populate new values.

 -(void)getPassengerinfo:(NSMutableArray*)arr{
  passenger_infoArray =[[NSMutableArray alloc]init];
  passenger_infoArray = arr;
  NSLog(@"Passenger Info Array : %@", passenger_infoArray);//Shows array of dictionaries

  [passengerInfoTableView reloadData];
}

My cellForRow method looks like this:

   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   //Not called when I am doing reload data
   static NSString *CellIdentifier = @"Cell";
   cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil)
   {
       cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier ];

   }
   NSLog(@"Table view array  : %@",passenger_infoArray); 
   if (passenger_infoArray.count>0) {

    NSString *temp= [[passenger_infoArray objectAtIndex:indexPath.row]objectForKey:@"firstName"];
    cell.textLabel.text = temp;
   }else{

    cell.textLabel.text = [NSString stringWithFormat:@"Passenger %ld", (long)indexPath.row+1];
    cell.imageView.image = [UIImage imageNamed:@"user.png"];

   }
     return cell;

  }
3

There are 3 best solutions below

4
Indrajeet On

You can pass data to previous view controller by using delegate method

In PassengerInfoViewController.h add below code just above of your import statement

@protocol passengerInfoViewControllerdelegate <NSObject>
     -(void)sendData:(NSMutableArray *)arrData; 
@end

After this create one property, as shown below

@property(nonatomic,assign)id delegate;

Now, in PassengerInfoViewController.m synthesize the property and after that

-(void)viewWillDisappear:(BOOL)animated
{
    [delegate sendData:yourArray];
}

Now in tableview

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    PassengerInfoViewController *pivc = [self.storyboard instantiateViewControllerWithIdentifier:@"PassengerInfoViewController"];

    pivc.delegate = self;  //Add this line to your code

   [self.navigationController pushViewController:pivc animated:YES];
}

Now, it's time to implement delegate method which we created in viewcontroller

-(void)sendData:(NSMutableArray *)arrData
{
      passenger_infoArray = arrData;
     [passengerInfoTableView reloadData];
}
0
naresh On

You can pass data using

  1. Delegates
  2. Notifications
  3. Properties
  4. Global variables

Using Delegates is good practice, and last two are not preferred.

2
bpapa On

Old way to do this was using delegates. Better way to do this is via an unwind segue because there's much less code and you don't have to create a protocol.

Once your form completes, your PDC should call [self performSegue:@"theNameOfTheUnwindSegueeYouCreateInTheStoryboard"]. Then, in your PDC's prepareForSegue method, get the destinationViewController property from the storyboardSegue parameter - this is your VC containing the Table View. Set whatever model property you're using to back the table view - in your case it looks to be the passenger_infoArray object, which you'll have to make mutable if isn't already and also expose publicly if it isn't already.