UISearchDisplayController без результатов tableView?

Как правило, UISearchDisplayController при активации отключает tableView и фокусирует SearchBar. Как только вы вводите текст в searchBar, он создает searchResultsTableView, который отображается между SearchBar и клавиатурой. Делегатор searchDisplayController вызывается, когда этот второй UITableView загружается/отображается/скрыт/выгружен. Обычно он показывает результаты поиска в реальном времени или записи автозаполнения при вводе.

В моем приложении я хочу выполнить поиск в веб-сервисе, и я не хочу вызывать веб-сервис для каждой буквы, которую вводит пользователь. Поэтому я хочу полностью отключить searchResultsTableView и сохранить затемненный черный оверлей, когда он войдет в текст. Затем я запускаю поиск (с экраном загрузки), когда он нажимает кнопку поиска.

Простое возвращение нулевых строк для searchResultsTableView не выглядит красивым, так как оно отображает пустой поискResultsTableView с сообщением "нет результатов". Я попытался скрыть таблицу, когда она появится (searchDisplayController:didLoadSearchResultsTableView:), которая работает, но затемненный затемненный оверлей также скрыт, так что базовый tableView снова будет снова виден.

Любые идеи, кроме воссоздания функциональности UISearchDisplayController с нуля?

Ответ 1

вот небольшой трюк, который я только что понял а также вы должны вернуть 0 результатов при редактировании searchstring

- (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

Вы пробовали это:

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

Таким образом, если пользователь вводит другой char в течение 1/5 секунд, вы делаете только один веб-вызов.

Ответ 3

Ничего из вышеперечисленного, похоже, не сработало хорошо, поэтому я придумал следующее (вы должны вызвать removeTableHeader, когда будете готовы отображать свои результаты):

- (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];
}

Очевидно, что он делает таблицу прозрачной, добавляет заголовок таблицы черного/полупрозрачного стола с тем же размером, что и таблица, и отключает прокрутку по таблице, чтобы вы не могли получить выше или за заголовком. В качестве бонуса вы можете добавить что-то в заголовок ( "please wait..." или индикатор активности).

Ответ 4

Имел ту же проблему, что и вы, я обработал ее с помощью a), установив альфа поискаResultsTableView на 0 при начале поиска, а затем b) добавление/удаление overlayView в представлении 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

должно быть достаточно реализовать следующий метод в вашем UISearchDisplayDelegate (который обычно является вашим пользовательским подклассом UITableViewController)

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

Вы пробовали это?

Ответ 6

На основе кода user182820 ниже приведена моя версия. Я скрываю представление таблицы 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

Как просто сделать это так просто:

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

Прекрасно работает для меня.

Ответ 8

Я лучше понимаю, так как есть ошибка с "лучшим ответом" - разделитель и "Нет результатов" будут показаны при прокрутке таблицы черного фона.

- (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

Все существующие ответы чересчур сложны. Вы можете уйти, просто скрыв представление таблицы результатов сразу.

-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
    tableView.hidden = YES;
}

Ответ 10

Думаю, я нашел лучшую реализацию для этой проблемы. Все предыдущие ответы правильно показывают тусклое представление, идентичное тому, что выглядит UITableView перед поиском, но для каждого решения не хватает функциональности, чтобы коснуться области, чтобы отменить поиск.

По этой причине я считаю, что этот код работает лучше.

Прежде всего, создайте 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 активен и что пользователь не нажал кнопку поиска.

Затем, в решающей степени, в didSelectRowAtIndexPath:

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, но вместо этого отменяет поиск.