Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to segue from a UISearchBarDisplayController result to a detailViewController

So, using storyboard you can create a segue from the UITableViewCell from the first tableViewController to a detailViewController.

Not too complicated, however, when a UISearchBarDisplayController is introduced into the storyboard mix, how can you segue the results cell to the detailViewController?

I am able to search without a problem, I followed this tutorial: http://clingingtoideas.blogspot.com/2010/02/uitableview-how-to-part-2-search.html

All I can do is select a row from the search, it turns blue and doesn't go to the detailViewController.

I have implemented the method prepareForSegue, which works for the non searched cells, but can't figure out this one.

like image 921
M Jesse Avatar asked Feb 17 '12 08:02

M Jesse


2 Answers

Here's the solution that's based on the comment by @James Chen. Also using a different IndexPath depending on which state the table is in.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

    if ([[segue identifier] isEqualToString:@"toDetail"]) {

        Person *person = nil;

        if (self.searchDisplayController.active == YES) {
            NSIndexPath *indexPath = indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
            NSLog(@"segue - section: %d, row: %d", indexPath.section, indexPath.row);

            person = [self.filteredPersonArray objectAtIndex:indexPath.row];
        }
        else {
            NSIndexPath *indexPath = indexPath = [self.tableView indexPathForSelectedRow];
            NSLog(@"segue - section: %d, row: %d", indexPath.section, indexPath.row);

            person = [self.personArray objectAtIndex:indexPath.row];
        }

        [[segue destinationViewController] setPerson:person];   

    }
}
like image 65
Nick N Avatar answered Sep 21 '22 03:09

Nick N


I tried your solution and found that prepareForSegue is called twice due to the life cycle and didSelect... -> performSegueWithIdentifier.

  1. self:prepareForSegue: object on destination controller is set (with wrong index) because
  2. dest:viewDidLoad: the destination controller view is loaded after which
  3. self:didSelectRow...: the index is known and properly set.
  4. self:prepareForSegue: object is now correct but has no side effect.

I then focused on didSelect... and came up with this solution where I deleted the segue and pushed the view programmatically:

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

    CustomObj *custObj = nil;

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        custObj = [filteredListContent objectAtIndex:indexPath.row];
    } else {
        storeToDetail = [self.fetchedResultsController objectAtIndexPath:indexPath];
    }

    controller.custObj = custObj;

    [self.navigationController setNavigationBarHidden:NO];
    [self.navigationController pushViewController:controller animated:YES];
    // presentViewController::animated:completion is always full screen (see problem below)
}

I then experienced some problems going back because I follow a segue from a mapView, which lead to:

//DestinationViewController
- (IBAction)back:(id)sender
{
    [self.navigationController popToRootViewControllerAnimated:YES]; // list
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; // map
}

which is not the way to do it but for now it works.

However, the first part is easy and clean, and maybe it works for you too?!

like image 23
marrop Avatar answered Sep 19 '22 03:09

marrop