Domanda

Di solito, un UISearchDisplayController, quando attivato, oscura tableView e focalizza la barra di ricerca. Non appena si immette il testo nella barra di ricerca, viene creato un oggetto SearchResultsTableView che viene visualizzato tra la barra di ricerca e la tastiera. Il delegato di searchDisplayController viene chiamato quando questo secondo UITableView viene caricato / mostrato / nascosto / scaricato. Di solito mostra i risultati della ricerca in tempo reale o le voci di completamento automatico durante la digitazione.

Nella mia app, voglio cercare un servizio web e non voglio chiamare il servizio web per ogni lettera inserita dall'utente. Pertanto, desidero disabilitare completamente searchResultsTableView e mantenere l'overlay nero sfumato mentre inserisce il testo. Vorrei quindi attivare la ricerca (con una schermata di caricamento) una volta che preme il pulsante di ricerca.

Restituire zero righe per searchResultsTableView non sembra carino poiché mostra un searchResultsTableView vuoto con un " nessun risultato " Messaggio. Ho provato a nascondere la tabella quando appare ( searchDisplayController: didLoadSearchResultsTableView: ) che funziona, ma anche l'overlay oscurato oscurato viene nascosto in modo che il tableView sottostante sia nuovamente visibile.

Qualche idea oltre a ricreare la funzionalità UISearchDisplayController da zero?

È stato utile?

Soluzione

ecco un piccolo trucco che ho appena capito e devi anche restituire 0 risultati durante la modifica di 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
}

Penso che capirai cosa fare dopo

Altri suggerimenti

Hai provato questo:

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

In questo modo, se l'utente digita un altro carattere entro 1/5 sec, si effettua una sola chiamata Web.

Nulla di quanto sopra sembrava funzionare bene alla fine, quindi ho pensato a quanto segue (devi chiamare removeTableHeader quando sei pronto a visualizzare i risultati):

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

Ovviamente, rende la tabella trasparente, aggiunge un'intestazione di tabella nera / traslucida con le stesse dimensioni della tabella e disabilita lo scorrimento sulla tabella in modo da non poter superare o superare l'intestazione. Come bonus, potresti aggiungere qualcosa alla vista dell'intestazione ("per favore aspetta ..." o un indicatore di attività).

Ho avuto lo stesso problema, l'ho gestito da a) impostando l'alfa di searchResultsTableView su 0 all'inizio della ricerca, e quindi b) aggiungendo / rimuovendo overlayView alla vista viewController. Funziona come un incantesimo per me.

@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

dovrebbe essere sufficiente implementare il seguente metodo nel tuo UISearchDisplayDelegate (che di solito è la tua sottoclasse UITableViewController personalizzata)

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

hai provato questo?

In base al codice di user182820 di seguito è la mia versione. Nascondo la vista tabella di UISearchDisplayController. Quando un carattere viene inserito nella casella di ricerca, inserisco una "vista in grigio" in modo che sembri che la "vista in grigio" di UISearchDisplayController non sia mai scomparsa e quindi la rimuovo al termine della ricerca. Se inserisci alcuni caratteri e premi Annulla, la vista della tabella diventa brevemente bianca e non so come aggirare il problema.

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

Che ne dici di farlo semplicemente come questo:

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

Funziona bene per me ..

Ho trovato un modo migliore, dato che c'è un bug con la "migliore risposta" - il separatore e il "Nessun risultato" verrà mostrato quando si scorre la tabella di sfondo nero.

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

Tutte le risposte esistenti sono eccessivamente complicate. Puoi scappare nascondendo immediatamente la vista della tabella dei risultati.

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

Penso di aver trovato un'implementazione migliore per questo problema. Tutte le risposte precedenti mostrano correttamente una vista attenuata identica a come appare UITableView prima di una ricerca, ma ogni soluzione è priva della funzionalità di toccare l'area per annullare la ricerca.

Per questo motivo penso che questo codice funzioni meglio.

Prima di tutto, crea un BOOL come searchButtonTapped per indicare se il pulsante di ricerca è stato toccato. Di default è NO.

Quindi:

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

Questo dovrebbe essere chiaro ora in base alle altre risposte. Assicurati di ripristinare anche le impostazioni originali quando l'utente tocca il pulsante Cerca.

Inoltre, nel metodo cellForIndexPath aggiungere:

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

Per creare la stessa vista attenuata che viene mostrata prima di inserire il testo. Assicurati di applicare queste proprietà alla cella giusta, ovvero verifica quale UITableView è attivo e che l'utente non ha toccato il pulsante Cerca.

Quindi, soprattutto, in 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];

Ora l'utente può toccare l'area oscurata, che non comporterà una selezione visibile di UITableViewCell, ma annulla invece la ricerca.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top