在使用的UITableViewController时UISearchDisplayControlle

2019-07-17 22:55发布

我一直在试图简单的搜索功能在我的应用程序添加到TableViewController。 我跟着雷Wenderlich的教程。 我有一个的tableView了一些数据,我添加在故事板的搜索栏+显示控制器,然后我有这样的代码:

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

该标准的东西,但是当我在搜索栏中输入文字崩溃与此错误每次:

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中:

[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"BreedCell"];

瞧! 它的工作...只有你第一次搜索。 如果你回到原来的结果并重新搜索,应用程序具有相同的错误崩溃。 我想过,也许将所有的

if(!cell){//init cell here};

东西向cellForRow方法,但并不认为违背具有dequeueReusableCellWithIdentifier的全部目的:forIndexPath:方法? 无论如何,我迷路了。 我在想什么? 请帮忙。 谢谢你提前为所有的时间(:

亚历克斯。

Answer 1:

尝试使用self.tableView代替的tableView在dequeueReusableCellWithIdentifier:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"BreedCell"];

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

此代码工作得很好

注意

如果你有自定义高度的细胞,不使用

[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

使用这个代替

[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];


Answer 2:

为什么它在第一次运行的工作很好,但随后崩溃的原因,如果你退出了成绩表,然后回到另一个搜索,因为搜索显示控制器加载一个新UITableView每次进入搜索模式的时间。

通过搜索模式我的意思是,你已经挖掘的文本框,你已经开始打字,此时产生的表视图中显示结果,退出该模式下,通过点击取消按钮来实现的。 当您点击文本字段第二次,并开始再次键入 - 这是进入“搜索模式”的第二次。

因此,为了避免撞车要注册的电池类表视图中使用searchDisplayController:didLoadSearchResultsTableView:委托方法(从UISearchDisplayDelegate的,而不是在你的控制器) viewDidLoad方法。

如下:

- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
    [tableView registerClass:[DPContentTableCell class] forCellReuseIdentifier:cellIdentifier];
    [tableView registerClass:[DPEmptyContentTableCell class] forCellReuseIdentifier:emptyCellIdentifier];
}

这抓住了我大吃一惊,因为在iOS 7 ...表视图被重用。 所以,你可以在注册类viewDidLoad如果你喜欢。 对于传统的缘故,我会继续我的注册在我提到的委托方法。



Answer 3:

搜索的cellForRowAtIndexPath方法中,“的tableView”之后,似乎不是您定义的表的一个实例。 所以,你可以使用定义细胞的表的实例。 代替:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

使用:

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

(不要使用的cellForRowAtIndexPath方法,使用self.tableView的tableView。)



Answer 4:

出列,而无需使用“indexPath”和在你的情况下获得一个零元素的单元格,则必须手动分配它。

- (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为离队的细胞,当你有一个切片主列表和一个普通的搜索列表可能会造成崩溃。 这段代码在任何情况下,而不是工作。



Answer 5:

当我有这个问题,将溶液替换tableView与@yourcell:dequeueReusableCellWithIdentifier self.tableView



Answer 6:

我的工作在该教程还。 默认TableViewController有“forIndexPath”,并在他的例子也并不存在。 一旦我删除它的搜索工作。

//Default code
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

//Replace with
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


Answer 7:

为迅速3,你只需要添加自:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! YourCell

    ...
}


文章来源: Assertion failure when using UISearchDisplayController in UITableViewController