UISearchDisplayController без результатов tableView? - PullRequest
42 голосов
/ 31 июля 2009

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

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

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

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

Ответы [ 10 ]

38 голосов
/ 02 октября 2009

вот небольшой трюк, который я только что понял а также вы должны вернуть 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
}

Я думаю, вы поймете, что делать дальше

19 голосов
/ 10 сентября 2009

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

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

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

9 голосов
/ 30 января 2012

У меня была та же проблема, что и у вас, я решил ее с помощью a) , установив альфа searchResultsTableView равным 0 при начале поиска, а затем 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
9 голосов
/ 03 сентября 2011

В конце концов ничего из вышеперечисленного не сработало, поэтому я пришел к следующему (вы должны вызвать 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];
}

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

2 голосов
/ 05 ноября 2012

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

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

У меня отлично работает ..

2 голосов
/ 28 марта 2010

Основанный на коде пользователя 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;
}   
2 голосов
/ 01 августа 2009

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

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

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

1 голос
/ 24 июня 2014

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

-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
    tableView.hidden = YES;
}
1 голос
/ 17 августа 2010

Я нашел лучший способ, так как есть ошибка с «лучшим ответом» - разделитель и «Нет результатов» будут отображаться при прокрутке таблицы на черном фоне.

- (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 ....
}
0 голосов
/ 02 ноября 2011

Я думаю, что нашел лучшую реализацию для этой проблемы. Все предыдущие ответы правильно показывают тусклое представление, идентичное тому, как выглядит 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, а вместо этого отменит поиск.

...