Search code examples
iosobjective-cuitableviewuistoryboardsegue

How to transition from UITableViewCell to another view controller


I am trying to go from a UITableView with prototype cells to a detailviewcontroller of the item I selected on.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"historyToDetail"])
    {
        BYFHistoryDetailViewController *controller = (BYFHistoryDetailViewController    *)segue.destinationViewController;
        controller.workOut = [[BYFWorkOut alloc] init];
        controller.workOut=_selectRow;
    }
}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    BYFHistoryTableViewController *detailViewController =[[BYFHistoryTableViewController alloc] init];

    NSArray *items = [[BYFworkOutStore sharedStore] allItems];
    BYFWorkOut *selectedItem = items[indexPath.row];
    _selectRow = selectedItem;
}

What is not happening is the transition from the table to detail I have a push segue from the prototype cell to the details.

What am I missing?


Solution

  • You are doing quite a lot wrong here. When using segue's you don't create an instance of the class. You simply call:

    [self performSegueWithIdentifier:@"MySegue" sender:self];
    

    This will use the segue you have defined in the storyboard. Where MySegue is the segue ID you created.

    When you want to pass in data you use the callback

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        BYFHistoryDetailViewController *vc = (BYFHistoryDetailViewController *)[segue destinationViewController];
        vc.workOut = selectedItem;
    }
    

    But using this callback will mean you will need to store selectedItem somewhere after you click the row so you can access it here.

    EDIT

    Your code seems a bit odd here also.

    You set workout to a new object.

    detailViewController.workOut = [[BYFWorkOut alloc]init];
    

    Create another object from data.

    NSArray *items = [[BYFworkOutStore sharedStore] allItems];
    BYFWorkOut *selectedItem = items[indexPath.row];
    

    And then assign the new object, overwriting the previous one.

    //give detail view controller a pointer to the item object in row
    detailViewController.workOut = selectedItem;
    

    There is no need to have the first line of code at all

    EDIT 2

    If you only going to be using the one selected item at a time. you can do this in your UITableViewController class.

    @implementation MyTableViewControllerClass
    {
        BYFWorkOut *_selectedItem;
    }
    

    inside didSelectRowAtIndexPath:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
       NSArray *items = [[BYFworkOutStore sharedStore] allItems];
       _selectedItem = items[indexPath.row];
    }
    


    EDIT 3

    I've modified the code you posted here. You didn't add the first line of code i posted. Please look at this:

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if([segue.identifier isEqualToString:@"historyToDetail"])
        {
            BYFHistoryDetailViewController *controller = (BYFHistoryDetailViewController    *)segue.destinationViewController;
            controller.workOut = _selectRow;
        }
    }
    
    
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSArray *items = [[BYFworkOutStore sharedStore] allItems];
        _selectRow = items[indexPath.row];
    
       [self performSegueWithIdentifier:@"historyToDetail" sender:self];
    }