iOS UISearchDisplayController 不显示结果

Posted

技术标签:

【中文标题】iOS UISearchDisplayController 不显示结果【英文标题】:iOS UISearchDisplayController doesn't show results 【发布时间】:2015-01-28 11:11:39 【问题描述】:

UISearchDisplayController 有问题。我使用StoryboardUIViewController 添加了一个UITableView。 UITableViewDataSourceUITableViewDelegate 连接到 Storyboard 中的 myViewController。

我在 myViewController 中实现了 delegatesdatasources

UISearchBarDelegateUISearchDisplayDelegateUITableViewDataSourceUITableViewDelegate。 在表格视图中显示所有数据工作正常,但是当我开始搜索时,numberOfRowsInSection: 方法被调用,但之后cellForRowAtIndexPath: 没有被调用,searchResultsTableView 根本不显示。 有人可以帮我吗?

下面是UISearchDisplayDelegateUISearchBarDelegate 方法的代码。

编辑:

static NSString *ProductCellIdentifier = @"TKMProductTableCell";
@interface TKMSearchAllProductsTableVC () <UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate> 
    UISearchDisplayController *searchDisplayController;


@property (nonatomic, strong) NSArray *allProducts;
@property (nonatomic, strong) NSMutableArray *filteredProducts;
@property (nonatomic, strong) UISearchBar *searchBar;

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 

    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    if (tableView == searchDisplayController.searchResultsTableView) 
        return [_filteredProducts count];
     else 
        return [_allProducts count];
    


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    TKMProductTableCell *cell = [self.tableView dequeueReusableCellWithIdentifier:ProductCellIdentifier];

    // Configure the cell...
    [self configureProductCell:cell atIndexPath:indexPath inTableView:tableView];

    return cell;


- (void)configureProductCell:(TKMProductTableCell *)cell atIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView

    TKMProduct *product = nil;
    if (tableView == searchDisplayController.searchResultsTableView) 
        product = self.filteredProducts[indexPath.row];
     else 
        product = self.allProducts[indexPath.row];
    

    cell.lblTitle.text = product.name;


#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar

    [self.navigationItem setRightBarButtonItem:nil];
    searchBar.showsCancelButton = YES;

    searchBar.autocorrectionType = UITextAutocorrectionTypeNo;

    [searchDisplayController setActive:YES animated:YES];


-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar

    searchBar.showsCancelButton = NO;


- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar

    searchBar.showsCancelButton = NO;

    [searchBar resignFirstResponder];
    [searchDisplayController setActive:NO animated:YES];
    [self dismissViewControllerAnimated:YES completion:nil];


#pragma mark - UISearchDisplayDelegate

- (void)filterContentForSearchText:(NSString *)searchText

    [self.filteredProducts removeAllObjects];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
    _filteredProducts = [NSMutableArray arrayWithArray:[_allProducts filteredArrayUsingPredicate:predicate]];


- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView

    tableView.backgroundColor = [UIColor redColor];


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    
    if (![searchString isEqualToString:@""] && searchString != nil) 
        [self filterContentForSearchText:searchString];
        [searchDisplayController.searchResultsTableView setHidden:NO];
    

    return YES;

编辑 2

这是我的 UISearchDisplayController 代码:

searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;

这是故事板连接的屏幕截图:screenshoot of storyboard connections

编辑 3:

我刚刚在日志中发现UITableView's 框架在numberOfRowsInSection 方法中是CGRectZero

(lldb) po [searchDisplayController searchResultsTableView]
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: 0, 0; contentSize: 0, 0>

(lldb) po [self.searchDisplayController searchResultsTableView]
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: 0, 0; contentSize: 0, 0>

(lldb) po self.tableView
<UITableView: 0x136878e00; frame = (0 0; 320 504); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x17444dd70>; layer = <CALayer: 0x17422e300>; contentOffset: 0, 0; contentSize: 320, 117906>

(lldb) po tableView
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: 0, 0; contentSize: 0, 0>

【问题讨论】:

你能告诉我你在 UISearchBarDelegates 和 UISearchDislplayDelegates 方法中编写的代码 我刚刚添加了一个代码。 【参考方案1】:

建议

我可能有点跑题了,但你应该知道这一点。

不要使用UISearchDisplayController,因为它不再稳定了。

Apple 文档

重要提示:UISearchDisplayController 在 ios 8 中已弃用。(注意 UISearchDisplayDelegate 也已被弃用。)管理 在 iOS 8 中呈现搜索栏并显示搜索结果 稍后,改为使用 UISearchController。

Link

【讨论】:

某些东西被弃用并不意味着它不稳定。 @Lefteris 谁说它不稳定,我说它不会适应硬件和软件设备上的架构变化。很快 Apple 将不再支持该类,因此很快就会出现错误。【参考方案2】:

您是否检查过 numberOfRowsInSection 返回的内容。在 shouldReloadTableForSearchString 方法中执行 filterContentForSearchText 方法后,还要检查 _filteredProducts 数组大小。把NSLog放到每个方法里面,调试代码。

试试这个 NSPredicate 格式字符串:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like[cd] %@", searchText];

【讨论】:

是的,我用 numberOfRowsInSection 中的断点检查了它:_filteredProducts 的方法和大小是正确的。过滤器工作正常。 searchResultsTableView 根本不显示。 可能是“searchDisplayController.searchResultsTableView”的对象引用不正确。还要确保情节提要中的所有数据源连接以及 tableviewcontroller 和 searchviewcontroller 的委托。请提及您在代码中为 searchDisplayController 对象设置引用的位置。检查 searchDisplayController 对象的所有连接和委托。【参考方案3】:

您是否已将课程或自定义单元格笔尖注册到UISearchDisplayController 表?

我在 UISearchDisplayController 委托方法中做:

- (void)searchDisplayController:(UISearchDisplayController *)controller
  didLoadSearchResultsTableView:(UITableView *)tableView

    [tableView registerClass:[UITableViewCell class]
      forCellReuseIdentifier:CellIdentifier];

【讨论】:

没有任何作用。

以上是关于iOS UISearchDisplayController 不显示结果的主要内容,如果未能解决你的问题,请参考以下文章

IO复用阻塞IO非阻塞IO同步IO异步IO

四种IO模型‘阻塞IO/非阻塞IO/信号驱动IO/异步IO‘

5种IO模型阻塞IO和非阻塞IO同步IO和异步IO

网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

同步IO异步IO阻塞IO非阻塞IO之间的联系与区别

同步IO异步IO阻塞IO非阻塞IO之间的联系与区别