Eric Oboite Eric Oboite - 5 months ago 9
iOS Question

Passing row selection between view controllers

Using storyboard I currently have a static Uitableview. When a user selects a row from the Parent table view a new table view is displayed showing some options. Once the user selects a row from the new table view I want to dismiss the table and display the parent view controller back and have the user selection displayed in the cell. Pretty much a radio selection for a form.

Do I handle the dismissing of the view controller and passing of the data within the view will appear or did select row at index path? I been stuck on this for a while.

Answer

Use delegation. The child view controller defines a delegate protocol that the parent view controller implements. Before the parent view controller displays the child view controller, it sets itself as the delegate of the child view controller. When the user has selected a row or what ever in the child view, the child view controller calls a method on its delegate and dismisses itself.


I wrote a sample code for you: https://github.com/vikingosegundo/StateSelection

The Parent View Controller is the MasterViewController.
The Child View Controller is the StateSelectionViewController.

  • The StateSelectionViewController defines a protocol in it's header: StateSelectionDelegate and has a delegate property id<StateSelectionDelegate> delegate.

    @protocol StateSelectionDelegate <NSObject>
    -(void) selectedState:(NSString *)state forNation:(NSString *)nation;
    @end  
    
  • MasterViewController conforms to this protocol, it implements the only delegate method selectedState:forNation:.

    -(void)selectedState:(NSString *)state forNation:(NSString *)nation
    {
        self.statesDictionray[nation] = state;
        [self.tableView reloadData];
    }
    
  • During MasterViewController's prepareForSegue:, it sets itself a delegate of the destination view controller, which happen to be StateSelectionViewController.

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([[segue identifier] isEqualToString:@"showDetail"]) {
            NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
            NSString *selectedNation =[[[self.tableView cellForRowAtIndexPath:indexPath] textLabel] text];
            [[segue destinationViewController] setSelectedNation:selectedNation];
            [[segue destinationViewController] setDelegate:self];
        }
    }
    
  • Now the segue is executed and the StateSelectionViewController's tableview gets displayed.

  • Once the user tabs on one of the rows, StateSelectionViewController will call

    [self.delegate selectedState: <theState> forNation: <theNation>];
    

    and dismisses or pops itself. Note the switch to determine the way the controller was presented.

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
           [self.delegate selectedState:stateDictionary[_selectedNation][indexPath.row] forNation:_selectedNation];
           if(self.presentingViewController)
               [self dismissViewControllerAnimated:NO completion:NULL];
           else
               [self.navigationController popViewControllerAnimated:YES];
    
    }
    
Comments