0

我正在尝试遵循两个关于如何为 UITableView 实现搜索控制器的教程。到目前为止,这一切正常,我遇到的问题是搜索/过滤器本身:

教程链接: http: //www.appcoda.com/how-to-add-search-bar-uitableview/ http://code-ninja.org/blog/2012/01/08/ios-quick-tip-filtering -a-uitableview-with-a-search-bar/

其中一个链接建议使用 Predicate 方法,我可以按如下方式使用它:

NSPredicate *resultPredicate = [NSPredicate
                                predicateWithFormat:@"SELF contains[cd] %@",
                                searchText];
self.searchResults = [self.fbFriends filteredArrayUsingPredicate:resultPredicate];

这个问题是,上面没有考虑到我确实想要搜索 self.fbFriends 数组,但我想搜索该数组中的每个字典。该数组被设置为每个 fb 朋友都有一个字典,包括 @"id" 和 @"name"。该表按字母顺序显示名称 - 这一切都很好。

我希望能够在 self.fbFriends 数组中的字典中搜索并返回一个数组(self.searchResults),它是字典的过滤器数组。

第二个教程操作如下所示的另一条路线:

for (NSDictionary *friend in self.fbFriends) {
    NSRange textRange = [[friend objectForKey:@"name"]rangeOfString:searchText options:NSCaseInsensitiveSearch];
    if (textRange.location != NSNotFound) {
        [self.searchResults addObject:friend];
    } else {
        [self.searchResults removeObjectIdenticalTo:friend];
    }
}

这条路线的问题是我没有检查过滤后的 self.searchResults 数组中是否已经存在该对象,因此在键入每个字符后继续添加...我相信这可以解决,但我不认为这是最干净的方法。如果谓词是最好的,我怎样才能让它与上面详述的数组/字典布局一起使用?

编辑 - 从答案

self.searchResults = [self.fbFriends filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSDictionary *object, NSDictionary *bindings) {
     //get the value from the dictionary (the name value)
     NSString *name = [object objectForKey:@"name"];
                                                                 //check if the name contains the search string (you can change 
                                                                 //the validation to check if the name starts with 
                                                                 //the search string or ends etc.
    if([name rangeOfString:searchText].location != NSNotFound) {
        return YES;
    }
    return NO;
}]];
4

1 回答 1

3

您可以使用谓词的块形式,例如:

self.searchResult = [self.array filteredArrayUsingPredicate:[NSPredicate 
//since the array contains only dictionaries you can change the 
//type of the object which by default is `id` to NSDictionary
   predicateWithBlock:^BOOL(NSDictionart *object, NSDictionary *bindings) {
        //get the value from the dictionary (the name value)
        NSString *name = [object objectForKey:yourDictionaryNameKey];
        //check if the name contains the search string (you can change 
       //the validation to check if the name starts with 
       //the search string or ends etc.
      if([name rangeOfString:searchString].location != NSNotFound) { 
          return YES
      }
      return NO  
}]];

此外,您可能必须使用__block标识符声明 searchString。

于 2013-05-20T22:11:55.670 回答