UISearchDisplayController bez TableView wyników?

Zwykle Kontroler UISearchDisplayController, po aktywacji, przyciemnia widok tabeli i skupia pasek wyszukiwania. Po wprowadzeniu tekstu do paska wyszukiwania tworzy on widok searchResultsTableView, który wyświetla się między paskiem wyszukiwania a klawiaturą. Delegat searchDisplayController jest wywoływany, gdy ten drugi UITableView jest załadowany/pokazany/Ukryty / rozładowany. Zazwyczaj wyświetla wyniki wyszukiwania na żywo lub wpisy autocompletion podczas pisania.

W mojej aplikacji chcę wyszukać webservice i nie chcę wywoływać webservice dla każdej litery wpisanej przez użytkownika. Dlatego chcę całkowicie wyłączyć searchResultsTableView i zachować przyciemnioną czarną nakładkę podczas wprowadzania tekstu. Chciałbym następnie uruchomić wyszukiwanie (z ekranem ładowania) po naciśnięciu przycisku wyszukiwania.

Samo zwracanie zerowych wierszy dla searchResultsTableView nie wygląda dobrze, ponieważ wyświetla pusty searchResultsTableView z komunikatem "brak wyników". Próbowałem ukryć stół, gdy się pojawi (searchDisplayController:didLoadSearchResultsTableView:), która działa, ale zaciemniona nakładka jest również ukryta, dzięki czemu podstawowy widok tableView jest ponownie całkowicie widoczny.

Jakieś pomysły poza odtworzeniem funkcjonalności UISearchDisplayController od podstaw?

Author: Zargony, 2009-07-31

10 answers

Oto mała sztuczka, którą właśnie wymyśliłem a także musisz zwrócić 0 wyników podczas edycji 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
}

Myślę, że wymyślisz co dalej

 38
Author: user182820,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-16 03:47:52

Czy próbowałeś tego:

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

W ten sposób, jeśli użytkownik wpisze inny znak w ciągu 1 / 5sec, wykonujesz tylko jedno połączenie internetowe.

 19
Author: Raymond W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-07 12:20:48

Nic z powyższych nie wydawało się działać dobrze w końcu, więc wpadłem na następujący pomysł (musisz wywołać removeTableHeader, gdy jesteś gotowy, aby wyświetlić wyniki):

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

Oczywiście sprawia, że tabela jest przezroczysta, dodaje czarny / półprzezroczysty nagłówek tabeli o takim samym rozmiarze jak Tabela i wyłącza przewijanie tabeli, dzięki czemu nie można dostać się powyżej lub obok nagłówka. Jako bonus możesz dodać coś do widoku nagłówka ('proszę czekać..."lub wskaźnik aktywności).

 9
Author: Barry Haanstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-03 17:00:01

Miałem ten sam problem co Ty, załatwiłem go przez a) Ustawienie Alfy searchResultsTableView na 0 podczas rozpoczynania wyszukiwania, a następnie przez b) dodanie/usunięcie widoku nakładki do widoku viewcontrollera. Działa jak urok dla mnie.

@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
Author: cvursache,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-30 15:28:48

Powinno wystarczyć zaimplementowanie poniższej metody w Twojej podklasie UISearchDisplayDelegate (która zazwyczaj jest twoją podklasą uitableviewcontroller)

- (BOOL) searchDisplayController: (UISearchDisplayController *) controller shouldReloadTableForSearchString: (NSString *) searchString
{
    [self startMyCustomWebserviceSearchAsBackgroundProcessForString: searchString]; //starts new NSThread
    return NO; 
}
Próbowałeś tego?
 2
Author: xoconoxtle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-01 13:25:58

Na podstawie kodu user182820 poniżej jest moja wersja. Ukrywam Widok tabeli UISearchDisplayController. Po wpisaniu znaku w polu wyszukiwania umieszczam ' przyciemniony widok 'tak, aby uisearchdisplaycontroller' przyciemniony widok ' nigdy nie zniknął, a następnie usuwam go po zakończeniu wyszukiwania. Jeśli wpiszesz kilka znaków i naciśniesz anuluj, widok tabeli na krótko staje się cały biały i nie wiem, jak to obejść.

- (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
Author: Mark Horgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-28 19:54:13

A co z robieniem tego tak prosto:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
self.searchDisplayController.searchResultsTableView.hidden=YES;
return YES;
}
Mi pasuje..
 2
Author: ingenspor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-04 20:37:22

Wybrałem lepszy sposób, ponieważ pojawił się błąd z "najlepszą odpowiedzią" - separator i "brak wyników" zostaną wyświetlone podczas przewijania czarnej tabeli tła.

- (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 ....
}
 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 09:42:56

Wszystkie istniejące odpowiedzi są zbyt skomplikowane. Możesz uciec, po prostu ukrywając widok tabeli wyników natychmiast.

-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
    tableView.hidden = YES;
}
 1
Author: Chris Allwein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 17:15:17

Myślę, że znalazłem lepszą implementację tego problemu. Wszystkie poprzednie odpowiedzi poprawnie pokazują przyciemniony widok identyczny z tym, jak UITableView wygląda przed wyszukiwaniem, ale każde rozwiązanie nie ma funkcji stukania obszaru w celu anulowania wyszukiwania.

Z tego powodu myślę, że ten kod działa lepiej.

Przede wszystkim Utwórz BOOL, taki jak searchButtonTapped, aby wskazać, czy przycisk wyszukiwania został naciśnięty. Domyślnie jest to NO.

Wtedy:

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

To powinno być teraz jasne na podstawie innych odpowiedzi. Pamiętaj, aby przywrócić oryginalne ustawienia, gdy użytkownik dotknie przycisku wyszukiwania.

Ponadto w metodzie cellForIndexPath dodać:

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

W celu utworzenia tego samego widoku przyciemnionego, który jest wyświetlany przed wprowadzeniem tekstu. Upewnij się, że zastosowałeś te właściwości do właściwej komórki, np. sprawdź, która UITableView jest aktywna i czy użytkownik nie dotknął przycisku wyszukiwania.

Wtedy, w 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];

Teraz użytkownik może dotknąć zaciemnionego obszaru, co nie spowoduje widocznego zaznaczenia UITableViewCell, ale zamiast tego anuluje wyszukiwanie.

 0
Author: Willem Sleegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-01 20:22:33