代码之家  ›  专栏  ›  技术社区  ›  Zargony

没有结果的UISearchDisplayController tableView?

  •  42
  • Zargony  · 技术社区  · 16 年前

    通常,当激活UISearchDisplayController时,会使tableView变暗并聚焦搜索栏。在搜索栏中输入文本后,它将创建一个searchResultsTableView,显示在搜索栏和键盘之间。当加载/显示/隐藏/卸载第二个UITableView时,将调用searchDisplayController的委托。通常在键入时显示实时搜索结果或自动完成条目。

    在我的应用程序中,我想搜索Web服务,但我不想为用户输入的每个字母调用Web服务。因此,我想完全禁用searchResultsTableView,并在他输入文本时保留暗显的黑色覆盖。一旦他点击搜索按钮,我就会触发搜索(带有加载屏幕)。

    仅仅为searchResultsTableView返回零行看起来并不好,因为它显示一个空的searchResultsTableView,并显示一条“no results”消息。当桌子出现时,我试图把它藏起来( searchDisplayController:didLoadSearchResultsTableView: )这是可行的,但黑色的覆盖层也被隐藏,以便底层的tableView再次完全可见。

    除了从头开始重新创建UISearchDisplayController功能之外,还有其他想法吗?

    10 回复  |  直到 16 年前
        1
  •  38
  •   Sijmen Mulder    14 年前

    这是我刚刚想出的一个小把戏 在编辑searchstring时,还必须返回0个结果

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {
        savedSearchTerm = searchString;
    
        [controller.searchResultsTableView setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.8]];
        [controller.searchResultsTableView setRowHeight:800];
        [controller.searchResultsTableView setScrollEnabled:NO];
        return NO;
    }
    
    - (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
    {
        // undo the changes above to prevent artefacts reported below by mclin
    }
    

        2
  •  19
  •   beryllium    14 年前

    你试过这个吗:

    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_lookup:) object:nil];
    [self performSelector:@selector(_lookup:) withObject:txt afterDelay:0.20];
    

    这样,如果用户在1/5秒内键入另一个字符,您只需进行一次web调用。

        3
  •  9
  •   Barry Haanstra    14 年前

    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
        [self setTableHeader];
    }
    
    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
        [self setTableHeader];
    }
    
    - (void)setTableHeader {
        UIView *headerView = [[UIView alloc] initWithFrame:self.searchDisplayController.searchResultsTableView.frame];
        headerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
    
        [self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor clearColor]];
        [self.searchDisplayController.searchResultsTableView setScrollEnabled:NO];
        [self.searchDisplayController.searchResultsTableView setTableHeaderView:headerView];
    
        [headerView release];
    }
    
    - (void)removeTableHeader {
        [self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor whiteColor]];
        [self.searchDisplayController.searchResultsTableView setScrollEnabled:YES];
        [self.searchDisplayController.searchResultsTableView setTableHeaderView:nil];
    }
    

    显然,它使表格透明,添加一个与表格大小相同的黑色/半透明表格标题,并禁用表格上的滚动,使您无法越过标题。作为奖励,您可以在标题视图中添加一些内容(“请稍候…”或活动指示器)。

        4
  •  9
  •   cvursache    14 年前

    和你有同样的问题,我自己处理 (b) 向viewController的视图添加/删除覆盖视图。对我来说很有魅力。

    @interface MyViewController()
    //...
    @property(nonatomic, retain) UIView *overlayView;
    //...
    @end
    
    @implementation MyViewController
    @synthesize overlayView = _overlayView;
    
    //...
    
    - (void)viewDidLoad
    {
        //...
    
        //define your overlayView
        _overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 480)];
        _overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.8];
    }
    
    //hide the searchResultsTableView
    - (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
    {
        self.searchDisplayController.searchResultsTableView.alpha = 0.0f;
    }
    
    //when ending the search, hide the overlayView
    - (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
    {
        [_overlayView removeFromSuperview];
    }
    
    //depending on what the user has inputed, add or remove the overlayView to the view of the current viewController 
    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {   
    
        if ([searchString length]>0) 
        {
            [self.view addSubview:_overlayView];
        }
        else
        {
            [_overlayView removeFromSuperview];
        }
    
        return NO;
    }
    
    @end
    
        5
  •  2
  •   xoconoxtle    16 年前

    在UISearchDisplayDelegate(通常是自定义UITableViewController子类)中实现以下方法就足够了

    - (BOOL) searchDisplayController: (UISearchDisplayController *) controller shouldReloadTableForSearchString: (NSString *) searchString
    {
        [self startMyCustomWebserviceSearchAsBackgroundProcessForString: searchString]; //starts new NSThread
        return NO; 
    }
    

        6
  •  2
  •   Mark Horgan    16 年前

    基于用户182820的代码,下面是我的版本。我隐藏UISearchDisplayController的表视图。在搜索框中输入字符时,我会放置一个“暗显视图”,使其看起来像UISearchDisplayController的“暗显视图”从未消失,然后在搜索完成后将其删除。如果您输入一些字符并按“取消”,表格视图将短暂变为全白色,我不知道如何解决这个问题。

    - (void)viewDidLoad {
        ...
        tableViewMask=[UIView new];
        tableViewMask.backgroundColor = [UIColor blackColor];
        tableViewMask.alpha = 0.8;
    }
    
    - (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller{
        tableViewMask.frame=CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y+controller.searchBar.frame.size.height, self.tableView.frame.size.width, self.tableView.frame.size.height-controller.searchBar.frame.size.height);
        controller.searchResultsTableView.hidden=YES;
    }
    
    - (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller{
        [tableViewMask removeFromSuperview];
    }
    
    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
        if (searchString.length==0)
            [tableViewMask removeFromSuperview];
        else 
            [self.tableView addSubview:tableViewMask];
        [searchText autorelease];
        searchText=[searchString retain];
        return NO;
    }   
    
        7
  •  2
  •   ingenspor    13 年前

    就这么简单做怎么样:

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {
    self.searchDisplayController.searchResultsTableView.hidden=YES;
    return YES;
    }
    

    对我来说很好。。

        8
  •  1
  •   user398952 user398952    15 年前

    我找到了一个更好的方法,因为有一个带有“最佳答案”的bug——当滚动黑色背景表时,会显示分隔符和“无结果”。

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    
        controller.searchResultsTableView.backgroundColor = [UIColor blackColor];
        controller.searchResultsTableView.alpha = 0.8;
        controller.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    
        for(UIView *subview in tableView.subviews) {
            if([subview isKindOfClass:UILabel.class]) {
                subview.hidden = YES;
            }
        }
    
        return NO;
    }
    
    - (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    
        self.searchDisplayController.searchResultsTableView.backgroundColor = [UIColor whiteColor];
        self.searchDisplayController.searchResultsTableView.alpha = 1;
        self.searchDisplayController.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    
        for(UIView *subview in tableView.subviews) {
            if([subview isKindOfClass:UILabel.class]) {
                subview.hidden = NO;
            }
        }
    
        // search results and reload data ....
    }
    
        9
  •  1
  •   Chris Allwein    12 年前

    所有现有的答案都过于复杂。您只需立即隐藏结果表视图,就可以逃之夭夭。

    -(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
    {
        tableView.hidden = YES;
    }
    
        10
  •  0
  •   Willem Sleegers    14 年前

    出于这个原因,我认为这段代码工作得更好。

    首先,创建一个BOOL,比如searchButtonTapped,以指示搜索按钮是否被点击。默认情况下,它是否。

    然后:

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    if (!searchButtonTapped) {        
        // To prevent results from being shown and to show an identical look to how the tableview looks before a search
        [controller.searchResultsTableView setBackgroundColor:[UIColor clearColor]];
        [controller.searchResultsTableView setRowHeight:160];
        self.searchDisplayController.searchResultsTableView.scrollEnabled = NO;
    } else {
        // Restore original settings
        [controller.searchResultsTableView setBackgroundColor:[UIColor whiteColor]];
        [controller.searchResultsTableView setRowHeight:44];
        self.searchDisplayController.searchResultsTableView.scrollEnabled = YES;
    }
    
    return YES;
    }
    

    根据其他答案,这一点现在应该很清楚了。当用户点击搜索按钮时,请确保恢复原始设置。

    此外,在cellForIndexPath方法中添加:

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.contentView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.8];
    

    以创建在输入文本之前显示的相同暗显视图。确保将这些属性应用于正确的单元格,即检查哪个UITableView处于活动状态,并且用户没有点击搜索按钮。

    然后,至关重要的是,在DidSelectRowatineXpath中:

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        if (searchButtonTapped) {
               // Code for when the user select a row after actually having performed a search
        {
    else 
        [self.searchDisplayController setActive:NO animated:YES];
    

    现在,用户可以点击暗显区域,这不会导致UITableViewCell的可见选择,而是取消搜索。