如何延迟搜索结果出现在tableview中?

时间:2014-07-11 21:42:19

标签: ios objective-c uisearchbar

我是编程新手,特别是obj-c。 我正在iOS应用程序中开发一个搜索栏,它可以挖掘到一个非常大的数据库(8.000多个条目并且正在增长),但是一旦我输入搜索字段,它就会在打字时开始返回结果,因为它很大数据量,它几乎冻结了键盘。 我的猜测是让搜索在4位数之后开始,所以不是从8000多个条目中查找,而是从较小的子集中查找它,但是我写的代码在4位数后继续冻结...... / p>

任何提示?

谢谢,

这是我的代码:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSUInteger length = [searchText length];
    if (![NSString isEmpty:searchText] & (length > 3))
    {
        self.filteredItems = [self.sedi filterMatch:^BOOL(id elem)
                          {
                              Sede *sede = (Sede *)elem;
                                  NSArray *split = [searchText componentsSeparatedByString:@" "];

                                  return [sede.nome matchAll:split] ||
                                  [sede.descrizione matchAll:split] ||
                                  [sede.indirizzo matchAll:split] ||
                                  [sede.generi matchAll:split];
                              }
                                           contains:^BOOL(id elem)
                              {
                                  Sede *sede = (Sede *)elem;
                                  NSArray *split = [searchText componentsSeparatedByString:@" "];
                                  return [sede.nome containsAll:split] ||
                                  [sede.descrizione containsAll:split] ||
                                  [sede.indirizzo containsAll:split] ||
                                  [sede.generi containsAll:split];
                              }];
        [self.searchDisplayController.searchResultsTableView reloadData];
    }
}

1 个答案:

答案 0 :(得分:1)

首先,正如rmaddy所说,为了简单起见,让用户点击“搜索”按钮可能会更好。

那就是说,你应该能够用NSOperationQueue完成这个。

首先,创建一个ivar或属性:

NSOperationQueue *_searchOperationQueue;

然后,在某处初始化它,可能是viewDidLoad

_searchOperationQueue = [NSOperationQueue new];
_searchOperationQueue.maxConcurrentOperationCount = 1;

然后,您应该能够将代码包装在NSOperation中,如下所示:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    // cancel any existing search
    [_searchOperationQueue cancelAllOperations];

    // begin new search
    [_searchOperationQueue addOperationWithBlock:^{
        NSUInteger length = [searchText length];
        if (![NSString isEmpty:searchText] && (length > 3))
        {

          NSArray *filteredTemp = [self.sedi filterMatch:^BOOL(id elem)
                                  {
                                  Sede *sede = (Sede *)elem;
                                      NSArray *split = [searchText componentsSeparatedByString:@" "];

                                      return [sede.nome matchAll:split] ||
                                      [sede.descrizione matchAll:split] ||
                                      [sede.indirizzo matchAll:split] ||
                                      [sede.generi matchAll:split];
                                  }
                                               contains:^BOOL(id elem)
                                  {
                                      Sede *sede = (Sede *)elem;
                                      NSArray *split = [searchText componentsSeparatedByString:@" "];
                                      return [sede.nome containsAll:split] ||
                                      [sede.descrizione containsAll:split] ||
                                      [sede.indirizzo containsAll:split] ||
                                      [sede.generi containsAll:split];
                                  }];
              // update view on main thread
              dispatch_async(dispatch_get_main_queue(), ^{
                self.filteredItems = filteredTemp;
                [self.searchDisplayController.searchResultsTableView reloadData];
              });
        }
    }];
}

我使用了几乎与此相同的代码来过滤大型列表并获得非常好的结果。您只需要小心保持模型和视图同步,只需在主线程上访问它(这就是我最后所做的)。

最后要注意的是,您在代码中使用了按位“AND”(&)而不是条件“AND”(&&),我在答案中对此进行了更正。虽然它在这种特殊情况下实际上可能正常运行,但几乎肯定是一个错误,所以要小心。