Can not display target scene after click on row of SearchResultTableView in my navigation controller

661 views Asked by At

I want to filter a list of entries via UISearchBar and show the details after user clicks a result row. Full list view and details view are linked via a navigation controller. The normal use case (without search) works like charm:

 (ListOfAllEntries)
 => (direct click on row)
 ==> (Details view for row)

This is what should also work:

(ListOfAllEntries) 
=> (Search)                  - OK!
==> (ListOfFilteredEntries)  - OK!
===> (click on result row)          - OK!
====> (Details view for row) - BOOUUMMM! UI and Nav.Ctrl broken

I am using a UISearchBar (with UISearchDisplayController) to filter an underlying UITableView. As Apple recommends the filtered search results are displayed in the default second table view (searchDisplayController.searchResultsTableView) on top of my original table view with all entries.

Everything works fine - the entries are filtered, and I get the right result row indexpath. Until the user clicks a search result row and I want to push the details view for the selected row on top of the navigation controller. My target details view displays BUT then my program is broken in the following ways:

  1. the target view displays slided below the navigation bar (see image#2)
  2. If I press "BACK" on the navigation bar I get an empty screen (see image#3) and after a further BACK click my app crashes) uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'

I tried displaying the target view (scene) with a segue:

if (tableView == self.searchController.searchResultsTableView) {
    [self performSegueWithIdentifier: @"showFoods" sender: self];
}

and I tried to display the target view via direct push:

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

Both approaches result in the same wrong app behavior.

See my images:

  • Why is my details list below the navigation bar?
  • Why is the navigation stack garbled after I push my details scene?

Any hint would be appreciated.

UISearchbar in action:

UISearchbar in action

After click on search result row - my details scene slides below the navigation bar

After click on search result row - my details scene slides below the navigation bar

After pressing "BACK" the scene with all entries does not display

After pressing "BACK" the scene with all entries does not display

My storyboard. Note: The red arrow marks the problem. (The segue in the storyboard works well. But If I want to grammatically go the way of the red arrow, my UI is messed up!).

Red arrow way messes up the UI

1

There are 1 answers

1
DerWOK On BEST ANSWER

I found the solution.

The error is very unspecific. And thus other people with the same problem are hard to find. Finally I found one here: Navigating Backwards through a UINavigationController Error

Thanks to the above SO question I was put on the right track: I had to delete the content of my tableView: didSelectRowAtIndexPath: method.

Why that? As UISearchBar was a new topic for me, I read some tutorials and some SO questions. And all of them had put code inside tableView: didSelectRowAtIndexPath:. This code was intended to handle the click on a row on the search result table. See here: http://www.appcoda.com/how-to-add-search-bar-uitableview/ and here: Navigating Backwards through a UINavigationController Error

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        [self performSegueWithIdentifier: @"showRecipeDetail" sender: self];        
    }
}

For some reason, (maybe new iOS7 behaviour?!), this code is not necessary anymore. Even worse: this code produces the above problems, as iOS7 automaticall triggers the according segue on the search result table and my manuall trigger made a second segue to fire off. Two segues with the same source and target had caused the problems.

So I completely deleted my tableView: didSelectRowAtIndexPath: overwrite method and everything works like a charm!