UITableView 数据源必须从 tableView 返回单元格:cellForRowAtIndexPath

Posted

技术标签:

【中文标题】UITableView 数据源必须从 tableView 返回单元格:cellForRowAtIndexPath【英文标题】:UITableView dataSource must return cell from tableView:cellForRowAtIndexPath 【发布时间】:2014-04-03 16:13:40 【问题描述】:

我在ViewController 中添加的搜索栏有问题。

我收到以下错误:

Assertion failure in -[UISearchResultsTableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit/UIKit-2935.137/UITableView.m:6509
2014-04-03 18:08:24.355 MyFood[6405:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

configureCell:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath         
    //    ToDos *toDo = [self.fetchedResultsController objectAtIndexPath:indexPath];
    if (viewMode==AlphabeticalOrder) 
        Inventory *toDo=nil;
        if (self.searchDisplayController.isActive) 
            toDo = [searchResults objectAtIndex:indexPath.row];
         else 
            toDo=[inventoryProducts objectAtIndex:indexPath.row];
        
        cell.textLabel.text = toDo.inventoryProductName;
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateStyle:NSDateFormatterShortStyle];
        NSDate *dt = toDo.expireDate;
        NSString *dateAsString = [formatter stringFromDate:dt];
        cell.detailTextLabel.text = [NSString stringWithFormat:@"Until: %@", dateAsString];
     else 
        Inventory *toDo=nil;
        if (self.searchDisplayController.isActive) 
            NSDictionary *sectionDict=[searchResults objectAtIndex:indexPath.section];
            NSArray *sectionData=[sectionDict objectForKey:@"SECTION_DATA"];
            toDo = [sectionData objectAtIndex:indexPath.row];
         else 
            NSDictionary *sectionDict=[inventoryProducts objectAtIndex:indexPath.section];
            NSArray *sectionData=[sectionDict objectForKey:@"SECTION_DATA"];
            toDo=[sectionData objectAtIndex:indexPath.row];
        
        cell.textLabel.text = toDo.inventoryProductName;
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateStyle:NSDateFormatterShortStyle];
        NSDate *dt = toDo.expireDate;
        NSString *dateAsString = [formatter stringFromDate:dt];
        cell.detailTextLabel.text = [NSString stringWithFormat:@"Until: %@", dateAsString];
    

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell.
    [self configureCell:cell atIndexPath:indexPath];
    return cell;


代码搜索栏:

   - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
    
        if (searchText.length!=0) 
            if (viewMode==AlphabeticalOrder) 
                NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
                //            [searchResults removeAllObjects];
                //            [searchResults addObjectsFromArray:[inventoryProducts filteredArrayUsingPredicate:resultPredicate]];
                searchResults=[inventoryProducts filteredArrayUsingPredicate:resultPredicate];
             else 
                //-section mode
                NSMutableArray *newDataArray=[NSMutableArray array];
                for (NSMutableDictionary *aSectionDict in inventoryProducts) 
                    NSArray *sectionData=(NSArray*)[aSectionDict objectForKey:@"SECTION_DATA"];
                    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
                    NSArray *filteredArray=[sectionData filteredArrayUsingPredicate:resultPredicate];
                    NSDictionary *sectionDataModified=[NSDictionary dictionaryWithObjectsAndKeys:filteredArray,@"SECTION_DATA",[aSectionDict objectForKey:@"SECTION_TITLE"],@"SECTION_TITLE", nil];
                    [newDataArray addObject:sectionDataModified];
                
                searchResults=[NSArray arrayWithArray:newDataArray];
            
        
    

    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    
        [self filterContentForSearchText:searchString
                                   scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                          objectAtIndex:[self.searchDisplayController.searchBar
                                                         selectedScopeButtonIndex]]];

        return YES;
    

谁能帮忙?

【问题讨论】:

【参考方案1】:

由于添加了搜索栏,需要检查单元格是否为nil:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

 // This is added for a Search Bar - otherwise it will crash due to
//'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
if (!cell) 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


   // Configure the cell.
    [self configureCell:cell atIndexPath:indexPath];
    return cell;


【讨论】:

【参考方案2】:

当您使用 UISearchDisplayController 时,结果会显示在一个单独的 UITableView 中,该 UITableView 使用您的原始视图控制器作为委托和数据源。由于该 UITableView 未在您的故事板中设置(它是动态创建和加载的),因此它无法访问您的原型单元格。通过使用,我能够获得一个类似的示例:

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

我有点担心,因为您要求一个表格视图创建要在不同表格视图中使用的单元格。

似乎更好的方法是不要将您的单元格创建为原型单元格,而是在一个单独的 nib 文件中创建它们并从中加载它们。

您还应该阅读UISearchDisplayController 的文档,因为数据源和委托协议的其他一些细节需要更新以反映存在多个表视图在运行的事实。

【讨论】:

【参考方案3】:

这告诉您您的方法:cellForRowAtIndexPath 正在返回一个为零的单元格。这会产生此错误。

这里的这一行:UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

将是 nill,因为您从不为单元分配任何内容,也不对它做任何事情。

【讨论】:

你假设他没有使用故事板中指定的原型单元(考虑到现有事实,这是最安全的假设) 但是当我点击搜索栏时弹出错误,正常的tableView内容显示在视图中 我使用原型单元 搜索栏的代码在哪里?它会重新加载你的 tableView 吗?

以上是关于UITableView 数据源必须从 tableView 返回单元格:cellForRowAtIndexPath的主要内容,如果未能解决你的问题,请参考以下文章

如何在滚动时更新 UITableView 数据

如何从数组中过滤多个选定值并将其从 uibutton 加载到其他 uitableview

UITableView 数据源必须从 tableView 返回一个单元格:cellForRowAtIndexPath:异常

UITableView 数据源必须从 tableView 返回单元格:cellForRowAtIndexPath

UITableView 多个动作

如何填充 UITableView 部分标题?