我如何在情节提要中使用原型单元和搜索结果控制器

Posted

技术标签:

【中文标题】我如何在情节提要中使用原型单元和搜索结果控制器【英文标题】:How can i use prototype cell in storyboard with search result controller 【发布时间】:2013-01-07 07:44:33 【问题描述】:

我有tableview 与搜索结果控制器在搜索栏中搜索时收到此错误指示没有单元格并收到以下错误。如何在此方法CellForRowAtIndexPath 中创建我的prototype 单元格

代码:

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

 static NSString *CellIdentifier = @"HoCell";
Ho *cell;
Ho *item;

if (tableView == self.searchDisplayController.searchResultsTableView) 
    if (cell == nil)
    
        cell = [[Ho alloc]  initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"HoCell"];
    
    item = [searchResultsController objectAtIndexPath:indexPath];

else
    cell = (Ho*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    item = [fetchedResultsController objectAtIndexPath:indexPath];

cell.ho.text = item.name;

cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"se.png"]];

return cell;

错误:

*** Assertion failure in -[UISearchResultsTableView _configureCellForDisplay:forIndexPath:],  /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:5471
 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

【问题讨论】:

【参考方案1】:

这里可能有两种可能:

1) 您返回的数字大于您的数组计数 表视图:numberOfRowsInSection:。不要。

2) 您的一个或多个 cell# 插座未连接到您的笔尖,或者 没有连接到 UITableViewCell (或子类)。把它们挂起来 正确。

通过这个 Ray Wenderlich 的链接: How to Add Search Into a Table View

检查此SO问题:

1) UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath: Exception

2) ios 5 UISearchDisplayController crash

一个更漂亮的链接:Custom Prototype Table Cells and Storyboards 看看这个部分:

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

  UITableViewCell *cell = [tableView
            dequeueReusableCellWithIdentifier:UYLCountryCellIdentifier];
  if (cell == nil)
  
    [self.countryCellNib instantiateWithOwner:self options:nil];
    cell = self.countryCell;
    self.countryCell = nil;
  
  // Code omitted to configure the cell...
  return cell;

【讨论】:

我将情节提要与原型单元一起使用,并为原型单元创建了名为 (Ho) 的自定义类,并检查部分中的行数没有问题。我调查了 cellForRowAtIndexPath 中的问题 只要通过这个链接:useyourloaf.com/blog/2012/09/06/… 感谢 Bhavin,但仍然使用标准原型单元,如果我使用自定义类作为原型单元呢? 好的.. 我在我的答案中又添加了一个链接。只需检查一下,让我知道您的问题是否已解决。【参考方案2】:

您的代码似乎有问题。您检查 cell == nil,而它最初未设置为 nil。您根据搜索模式以这种方式分配单元格看起来也有点奇怪。

无论如何,我会以不同的方式来做。恕我直言,我这样做的方式几乎是规范的 :) 只需使用您的搜索结果为您的单元格填充每种情况下的正确数据(搜索模式和正常模式)。在此示例中,searchResult 和 dataSource 是带有字符串的数组。我认为在现实生活中对你来说这将是更复杂的东西,比如 nsdictionary 数组。

在您的视图控制器中:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)_section

        /* Use correct data array so that in search mode we draw cells correctly. */
        NSMutableArray *data = searching ? searchResult : dataSource;
        return [data count];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
       
        /* Use correct data array so that in search mode we draw cells correctly. */
        NSMutableArray *data = searching ? searchResult : dataSource;
        static NSString *CellIdentifier = @"CellId";

        CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
                cell = [[[CustomTableViewCell alloc] initWithIdentifier:CellIdentifier] autorelease];
        

        /* Note this is only correct for the case that you have one section */
        NSString *text = [data objectAtIndex:[indexPath row]]

        cell.textLabel.text = text;
        /* More setup for the cell. */
        return text;

这里是搜索控制器和一些助手的委托方法:

- (void) searchTableView

        NSString *searchText = searchBar.text;

        for (NSString *item in dataSource) 
                NSRange range = [item rangeOfString:searchText options:NSCaseInsensitiveSearch];
                if (range.length > 0) 
                        [searchResult addObject:item];
                
        


- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller

        searching = NO;


- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller

        searching = NO;
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
                      withRowAnimation:UITableViewRowAnimationAutomatic];
        [searchResult removeAllObjects];


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchText

        [searchResult removeAllObjects];

        if ([searchText length] > 0) 
                searching = YES;
                [self searchTableView];
         else 
                searching = NO;
        
        return YES;

希望这会有所帮助。

【讨论】:

我试了一下没有崩溃,但是表格视图是空的,看不到数据!【参考方案3】:

我也有同样的问题,这就是我们所做的,现在它运行良好..

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

    // Here is my code BEFORE
    //
    OPUsersTableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:TableCellID];

    // Here is my code AFTER
    //
    OPUsersTableViewCell *tableCell = [self.groupTableView dequeueReusableCellWithIdentifier:TableCellID];

注意:

self.groupTableViewprototype cell 所在的位置...

【讨论】:

以上是关于我如何在情节提要中使用原型单元和搜索结果控制器的主要内容,如果未能解决你的问题,请参考以下文章

从 Xib 加载原型单元

如何连接故事板中的原型单元?

如何在情节提要中向原型 UITableViewCell 添加渐变背景颜色?

来自 Prototype Cell 的 pushViewController

在笔尖而不是情节提要中制作原型单元

如何从 xib 文件 uiview 到情节提要 ViewController