0
votes

Originally, I have a main table view controller with a tableview of static cells laid out using Storyboards. Subsequently, I added a SearchDisplayController to this UITableViewController. In my tableview data source delegate methods such as numberOfSectionsInTableView: and numberOfRowsInSection, I am differentiating between my own tableview (with the static cells) and the searchResultsTableView of the search display controller by checking the following:

if (tableView == self.searchDisplayController.searchResultsTableView)
{
   // logic for searchResultsTableView;
}
else
{
  // logic for my main tableView
}

As far as I know, this seems to be the right approach. But when I tried the following for the cellForRowAtIndexPath method, I am getting a crash with the message Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        // Just want to use a default cell. There seems to be no good way of specifying a prototype cell for this in the storyboard.
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if ( cell == nil ) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        return cell;
    }
    else
    {
         // how to handle this case?
         return nil;
    }
}

Previously, without the search display controller, I didn't have to implement this method as my cells are static. I guess my question is, how should I handle a hybrid case (in cellForRowAtIndexPath as well as specifying both kinds of cells in the same storyboard), where I have a search display controller tableview with dynamic cells and a tableview with static cells? I would imagine such a scenario to be not uncommon.

Thanks in advance!

EDIT:

While calling the super method in the else clause as suggested by the first commenter seemed to fix the crash, I am encountering yet another issue which I feel is somehow due to inherent issues of the tableViewController being a delegate of both a static tableview and a non-static one (the search display results table view).

The new issue: My static tableview has 2 static cells. When I populate my search results tableview with more than 2 rows, I get a NSRangeException', reason: -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1].

It seems like the searchResultsTableView derived the number of rows from my main static tableview somehow (results were consistent when I added a 3rd static cell) even though the delegate method: numberOfRowsInSection was being fired for the case of searchResultsTableView, and returning the right number.

Any workarounds on making static tableviews play nice with search display tableviews? I am thinking of converting my main static tableview to one with dynamic cells.. Any other suggestions are welcome, thanks!

4
I'm not sure, but have you tried return [super tableView:tableView cellForRowAtIndexPath:indexPath]?maroux
You do it the same way as you do when tableView == self.searchDisplayController.searchResultsTableView returns true. You need to create yourself some cells, either in IB or programmatically, and create and return the appropriate one for your needs, probably based on the indexPath.Remover
Calling the super method works. Thanks!Ken Toh
I'm not sure why calling super would work, but you're not supposed to implement the table view data source methods at all for a static table view (their cells should be populated through IBOutlets). I would think the correct approach would be to get rid of the else clause all together.rdelmar
@rdelmar,you might have a point. The super method solved the initial crash but I am encountering new problems which I suspect might be due to the tableviewcontroller being a delegate of both a static tableview and a non-static one. I have updated my question with the new issues. Anyway, cellForRowAtIndexPath must return a UITableViewCell, so I am not sure how to just get rid of the else clause. Mmm any other ideas?Ken Toh

4 Answers

1
votes

My workaround in the end was to convert the static tableview into one with dynamic cells. It isn't pretty but it works.

0
votes

I faced this problem too. So my decision was create some class with protocol, and then just assign it as DataSource to UISearchDisplayViewController.

0
votes

You don't need to change your static cells for dynamic cells. You can do the following:

if (tableView == self.searchDisplayController.searchResultsTableView)
{
   // logic for searchResultsTableView;
}
else
{
   UITableViewCell *cell = [super tableView:tableView
                       cellForRowAtIndexPath:indexPath];
   return cell;

}
0
votes
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        // Just want to use a default cell. There seems to be no good way of specifying a prototype cell for this in the storyboard.
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if ( cell == nil ) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        return cell;
    }
    else
    {
          UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
         return cell;
    }
}

this would work fine for your problem.