2014-04-03 126 views
5

我在我的搜索欄中添加了一個問題,我在ViewController中添加了該問題。UITableView dataSource必須從tableView中返回單元格:cellForRowAtIndexPath

我收到以下錯誤:

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; 
    } 

誰能幫助?

回答

0

這是告訴你,你的方法:cellForRowAtIndexPath正在返回一個零的單元格。這會產生這個錯誤。

這條線的位置:UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

將是nill,因爲你永遠不指定任何細胞,也不是你用它做任何事情。

+0

你假設他沒有使用故事板指定的原型細胞(這是考慮到最安全的前提事實在手) –

+0

但當我點擊搜索欄時彈出錯誤,正常的tableView內容顯示在視圖中 – user3450607

+0

我使用原型單元格 – user3450607

5

當您使用UISearchDisplayController時,結果顯示在一個單獨的UITableView中,該UITableView使用原始視圖控制器作爲委託和數據源。由於該UITableView沒有在故事板中設置(它是動態創建和加載的),因此它無法訪問您的原型單元。我能得到一個類似的例子,通過使用工作:

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

我有點擔心,既然你問一個tableview中創建的細胞在不同的表視圖中使用。

看來更好的方法是不創建單元格作爲原型單元格,而是創建它們並從單獨的nib文件加載它們。

您還應該閱讀UISearchDisplayController的文檔,因爲還需要更新dataSource和委託協議的其他幾個細節以反映有多個表視圖在使用這一事實。

14

既然你已經添加了一個搜索欄,您需要檢查,如果該細胞是不是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; 

} 
+0

這個答案適合我。謝謝! – Leandro

相關問題