搜索核心数据支持的UITable问题?

时间:2009-10-21 22:08:02

标签: search uitableview core-data

不确定这是不是正确的地方(我相信有人会告诉我,如果不是这样的话)我有一个iPhone应用程序,它有一个由核心数据支持的UITableview。我想执行缩小搜索,以便仅显示以在搜索栏中输入的字符开头的项目。这通常是使用委托 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText没问题。我有点困惑,因为我是Core Data的新手,如何做到这一点。我认为其中一个重大问题是更新界面,让它知道要呈现什么。我假设需要将另一个NSFetchedResultsController发送到UITableView是否正确?

所以这是我的问题: 1)我假设我需要创建一个只包含正确项目的NSFetchedResultsController,然后告诉UITableView将其用作dataSource并重新加载表格? 2)有没有比执行完全排序的获取和删除那些不符合的对象更好的方法。即有没有办法做一个选择类型获取?

如果这是一个愚蠢的问题,请提前致谢并抱歉。

此致 达明

2 个答案:

答案 0 :(得分:2)

  1. 是的,你需要一个新的NSFetchedResultsController。
  2. 您应该在新的NSFetchRequest中使用NSPredicate来过滤搜索文本。
  3. 例如,如果您的托管对象有一个应该过滤的字段“名称”:

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K beginswith[c] %@", @"name", searchText];
    [fetchRequest setPredicate:pred];
    

答案 1 :(得分:0)

我使用了一个稍微不同的解决方案:我不是依赖于不同的NSFetchedResultsController,而是在我的表视图控制器中创建了一个NSMutableArray(filteredListContent),用于存储临时数据,受Apple sample code和{{3的启发}}。

在tableView:cellForRowAtIndexPath:中,返回相应的数据源数组:

if(receivedTableView == self.searchDisplayController.searchResultsTableView){
        Objects* object = [self.filteredListContent objectAtIndex:indexPath.row];
        cell.textLabel.text = object.name;
    } else {
        Objects* object = [self.unfilteredListContent objectAtIndex:indexPath.row];
        cell.textLabel.text = object.name;
    }

与Apple的示例代码一样,在其他方法中添加几乎相同的方法,例如

- (NSInteger)tableView:(UITableView *)receivedTableView numberOfRowsInSection:(NSInteger)section {

    if(receivedTableView == self.searchDisplayController.searchResultsTableView){
       return [self.filteredListContent count];
    }

    return [self.unfilteredListContent count];
}

以及tableView:didSelectRowAtIndexPath:... 然后符合UISearchDisplayDelegate协议并添加了以下方法:

- (void)filterContentForSearchText:(NSString*)searchText
{

    if (!self.filteredListContent) {
        self.filteredListContent = self.filteredListContent = [[NSMutableArray alloc] init];
    }

    [self.filteredListContent removeAllObjects];


    for (Objects *object in [self.coreDataStuffVariable.fetchedResultsController fetchedObjects])
    {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                  @"(SELF contains[cd] %@)", searchText];

        NSString * elementTitle = [NSString stringWithFormat:@"%@", object.name];

        [elementTitle compare:searchText options:NSCaseInsensitiveSearch];

        if([predicate evaluateWithObject:elementTitle])
        {
            [self.filteredListContent addObject:password];
        }
    }
}



- (BOOL)searchDisplayController:(UISearchDisplayController *)controller 
shouldReloadTableForSearchString:(NSString *)searchString{
    [self filterContentForSearchText:searchString];
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

非常简单。我想如果在搜索过程中重新加载核心数据对象会导致结果很糟糕......但是如果你知道这可能是一个很好的解决方案就可以睡觉了!