首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在UITableViewController中使用UISearchDisplayController时断言失败

在UITableViewController中使用UISearchDisplayController时断言失败
EN

Stack Overflow用户
提问于 2013-01-08 09:56:57
回答 5查看 18.3K关注 0票数 80

我一直在尝试将简单的搜索功能添加到我的应用程序的TableViewController中。我遵循了雷·温德利希的教程。我有一个包含一些数据的tableView,我在storyboard中添加了搜索栏+显示控制器,然后我有了以下代码:

代码语言:javascript
复制
#pragma mark - Table View
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BreedCell" forIndexPath:indexPath];

        //Create PetBreed Object and return corresponding breed from corresponding array
        PetBreed *petBreed = nil;

        if(tableView == self.searchDisplayController.searchResultsTableView)
            petBreed = [_filteredBreedsArray objectAtIndex:indexPath.row];
        else
            petBreed = [_breedsArray objectAtIndex:indexPath.row];

        cell.accessoryType  = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text = petBreed.name;

        return cell;
    }

#pragma mark - Search
    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
        [_filteredBreedsArray removeAllObjects];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchString];
        _filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy];

        return YES;
    }

    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
        // Tells the table data source to reload when scope bar selection changes

        [_filteredBreedsArray removeAllObjects];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",self.searchDisplayController.searchBar.text];
        _filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy];
        return YES;
    }

这是标准的东西,但是当我在搜索栏中输入文本时,它每次都会崩溃,并显示以下错误:

代码语言:javascript
复制
2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460
2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier BreedCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

我知道在iOS 6中,信元的处理和出列系统发生了变化,而且搜索使用了不同的tableView,所以我认为问题是带有过滤结果的搜索tableView不知道该信元,所以我在我的viewDidLoad中放入了以下内容:

代码语言:javascript
复制
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"BreedCell"];

瞧!它成功了..。只有在你第一次搜索的时候。如果您返回到原始结果并再次搜索,应用程序崩溃并返回相同的错误。我想也许可以添加所有的

代码语言:javascript
复制
if(!cell){//init cell here};

填充到cellForRow方法中,但这是否与拥有dequeueReusableCellWithIdentifier:forIndexPath:方法的全部目的背道而驰呢?不管怎么说,我迷路了。我遗漏了什么?请帮帮忙。提前感谢您的宝贵时间(:

亚历克斯。

EN

回答 5

Stack Overflow用户

发布于 2013-08-14 17:48:26

它在第一次运行时运行良好,但如果您退出结果表并返回进行另一次搜索,则会崩溃,这是因为每次您进入搜索模式时,搜索显示控制器都会加载一个新的UITableView

通过搜索模式,我的意思是,你已经点击了文本字段,你已经开始输入,在这一点上,一个表视图被生成以显示结果,退出该模式是通过点击取消按钮来实现的。当您第二次点击文本字段并再次开始键入时-这是第二次进入“搜索模式”。

因此,为了避免崩溃,您应该为表视图注册单元格类,以便在searchDisplayController:didLoadSearchResultsTableView:委托方法(来自UISearchDisplayDelegate)中使用,而不是在控制器的viewDidLoad方法中使用。

如下所示:

代码语言:javascript
复制
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
    [tableView registerClass:[DPContentTableCell class] forCellReuseIdentifier:cellIdentifier];
    [tableView registerClass:[DPEmptyContentTableCell class] forCellReuseIdentifier:emptyCellIdentifier];
}

这让我大吃一惊,因为在iOS 7上...表视图正在被重用。因此,如果您愿意,可以在viewDidLoad中注册该类。考虑到遗留问题,我将保留我提到的委托方法中的注册。

票数 14
EN

Stack Overflow用户

发布于 2013-04-24 22:51:06

在不使用“indexPath”的情况下将单元格排出队列,如果您获得了nil元素,则必须手动分配它。

代码语言:javascript
复制
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YourCellId"];
    if (!cell)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YourCellId"];

    // fill your cell object with useful stuff :)

    return cell;
}

当您有一个分段的主列表和一个普通的搜索列表时,尝试使用self.tableView将单元出队可能会导致崩溃。相反,这段代码在任何情况下都可以工作。

票数 3
EN

Stack Overflow用户

发布于 2014-10-03 04:23:50

当我遇到这个问题时,解决方案是用self.tableView替换tableView的出队可重用性单元和标识符:@yourcell

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14207142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档