UISearchBar搜索带有文本,子文本和图像的表格行

时间:2011-06-10 07:05:53

标签: objective-c ios ios4 iphone-sdk-3.0

我注意到,为了搜索表格,必须将该数据的副本插入到搜索数组中。

E.g。

    //Initialize the array.
listOfItems = [[NSMutableArray alloc] init];

NSArray *countriesToLiveInArray = [NSArray arrayWithObjects:@"Iceland", @"Greenland", @"Switzerland", @"Norway", @"New Zealand", @"Greece", @"Rome", @"Ireland", nil];
NSDictionary *countriesToLiveInDict = [NSDictionary dictionaryWithObject:countriesToLiveInArray forKey:@"Countries"];

NSArray *countriesLivedInArray = [NSArray arrayWithObjects:@"India", @"U.S.A", nil];
NSDictionary *countriesLivedInDict = [NSDictionary dictionaryWithObject:countriesLivedInArray forKey:@"Countries"];

[listOfItems addObject:countriesToLiveInDict];
[listOfItems addObject:countriesLivedInDict];

//Initialize the copy array.
copyListOfItems = [[NSMutableArray alloc] init];

所搜索的是存储在复制数组中的对象。

我的问题是,如何在特定单元格中搜索包含文本,子文本和图像的单元格行。

2 个答案:

答案 0 :(得分:3)

(1)

搜索桌子的确没有。当用户在UISearchBar中输入文本时会发生什么事情完全取决于您 - 您可以将该操作视为您喜欢的任何内容。您所要做的就是充当结果表的委托和数据源,并形成结果表,以响应构成任何表格基础的标准三大问题(“您有多少部分?有多少部分?”这部分中的行?这行的单元格是什么?“)以你喜欢的任何方式。结果表通常看起来像原始表的简化版本,但这根本不需要!它可以是您想要的任何表格。

(2)

不要将Model与View混淆。该表只是一个视图。您的数据是模型。它是您要搜索的模型,您的数据是原始表的基础。因此,当用户键入您的UISearchBar并开始搜索时,您希望形成一个新模型,该模型将成为结果表的基础。你如何形成它完全取决于你。通常,您需要过滤原始模型,以便结果模型中剩下的唯一内容是计为有效结果的内容。您可以通过遍历整个原始模型,将与搜索标准相匹配的所有内容放入新模型中来实现此目的。或者,如果原始模型是一个数组,您可以使用其中一个filteredArray方法来帮助您。最灵活的方法是使用块形成谓词,如本书中的示例所示:

NSPredicate* p = [NSPredicate predicateWithBlock:
                  ^BOOL(id obj, NSDictionary *d) {
                      NSString* s = obj;
                      NSStringCompareOptions options = NSCaseInsensitiveSearch;
                      return ([s rangeOfString:sbc.searchBar.text 
                                       options:options].location != NSNotFound);
                  }];
self.filteredStates = [states filteredArrayUsingPredicate:p];

在该示例中,s(数组中的一项)每次都是一个字符串,我正在查看用户的搜索词是否出现在该字符串中。但如果您有一个字典或其他结构同时包含标题和副标题以及有关图像的信息,您可以以任何您喜欢的方式检查该字典。根据这个数组项是否通过基于搜索项的测试返回YES或NO,只要附加到传递测试的概念。

(3)

剩下的大问题是形成结果模型时。我通常首先将结果模型与原始模型相同以响应searchDisplayControllerWillBeginSearch,否则结果表将在用户输入时说“无结果”。 (这可能就是为什么你认为首先要做的是复制原始模型。)然后,我可以进行实际过滤以响应searchBarSearchButtonClicked(用户输入并点击了搜索),或者模型足够小,我可以在用户输入的每个字母后重新过滤它,以响应searchBar:textDidChange(用户在搜索栏中输入了一个字母)。

答案 1 :(得分:2)

涉及几个步骤。请注意,下面的代码只是我现在手动输入的一个示例,因此它可能无法编译,只是为了给您一个想法。

1)确保您有一个包含所有单元格值的数组。

2)创建该数组的副本,并在表委托方法中返回单元格时将该副本用作数据源。

3)将自己设置为UISearchBar的委托,并回复其事件:

- (void)searchBarButtonClicked(UISearchBar *)searchBar {
    [self doSearch:searchBar.text];
}

- (void)searchBar(UISearchBar *)searchBar textDidChange:(NSString *)searchTerm {
    if (searchTerm.length == 0) {
        [self resetSearch];
        [table reloadData];
    }
    else
        [self doSearch:searchTerm];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    searchBar.text = @"";
    [self resetSearch];
    [table reloadData];
    [searchBar resignFirstResponder];
 }

4)创建其他方法

resetSearch方法只需要将完整的数据数组复制到表委托使用的数据源数组中:

- (void)resetSearch {
    self.tableSourceArray = [self.dataSourceArray copy]; // Or write a deep copy if you want to.
}

在搜索时,我们需要过滤datasource数组。您可以创建更高效​​的东西 - 这只是一个例子。

- (void)doSearch:(NSString *)searchTerm {

    NSMutableArray *filtered = [[NSMutableArray alloc] init];
    for (NSString *item in self.self.dataSourceArray) {
        if ([item rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound])
            [filtered addObject:[item copy]];
    }

   self.tableSourceArray = filtered;
}

那应该是它!