2012-03-10 2 views
17

sto cercando l'attuazione di un UISearchBar che recuperare le informazioni da un URL, e con il metodo di default:UISearchBar rilevare quando tipo di stop degli utenti e non cercare immediatamente in modo da rilevare pausa

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ 

posso rilevare immediatamente quando il testo cambia ed esegue il recupero dell'URL, ma in questo modo, il tipo di testo è lento perché l'iPhone sta cercando l'url, quindi voglio iniziare il recupero dell'URL quando l'utente smette di scrivere per qualche secondo, quindi voglio rilevare la pausa della digitazione per aggiornare la vista tabella recuperando le informazioni dall'URL. Ho trovato un vecchio post di questo richiesta e ho provato una soluzione che per me non lavoro:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(request:)  object:searchText]; 

    //..... 

    [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; 
} 

-(void)request:(NSString *)myString 
{ 
    NSLog(@"%@",myString); 
} 

in questo modo quando sto scrivendo il metodo di richiesta non viene chiamato, ma quando mi fermo a digitare E ' chiamato per ogni carattere che digito, quindi è lo stesso del metodo predefinito, ho sbagliato qualcosa? o l'implementazione non è corretta?

risposta

24

Sembra che la soluzione fornita non funziona perché l'argomento "Testo di ricerca" per cancelPreviousPerformRequestsWithTarget:selector:object: non corrisponde all'argomento "searchText" alla precedente chiamata a performSelector:withObject:afterDelay:; così le ricerche ritardate vengono messe in coda ogni cambio di testo e mai annullate.

È possibile utilizzare un NSTimer per ritardare l'invocazione della ricerca e annullare il timer ogni volta che il testo cambia: Assegnare all'oggetto una proprietà o campo NSTimer; in searchBar:textDidChange: annulla qualsiasi timer esistente, quindi creane uno nuovo e pianificarne uno nuovo. L'obiettivo del timer dovrebbe chiamare il tuo metodo di ricerca.

Qualcosa di simile (la parte superiore della mia testa):

// in your class' .h object fields 
{ 
    ... 
    NSTimer *searchDelayer; // this will be a weak ref, but adding "[searchDelayer invalidate], searchDelayer=nil;" to dealloc wouldn't hurt 
    ... 
} 

// in the .m 

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [searchDelayer invalidate], searchDelayer=nil; 
    if (YES /* ...or whatever validity test you want to apply */) 
    searchDelayer = [NSTimer scheduledTimerWithTimeInterval:1.5 
                target:self 
                selector:@selector(doDelayedSearch:) 
                userInfo:searchText 
                repeats:NO]; 
} 

-(void)doDelayedSearch:(NSTimer *)t 
{ 
    assert(t == searchDelayer); 
    [self request:searchDelayer.userInfo]; 
    searchDelayer = nil; // important because the timer is about to release and dealloc itself 
} 

Alcuni programmatori potrebbero essere meno disinvolto sui riferimenti deboli di quanto io sia qui.

[A cura di aggiungere:]

Ecco come si potrebbe farlo se si fosse imposta sull'utilizzo cancelPreviousPerformRequestsWithTarget ...:

// in your class' .h object fields 
{ 
    ... 
    NSString *priorSearchText; // this will NOT be a weak ref, so adding "[priorSearchText release]" to dealloc is also required 
    ... 
} 

// in the .m 
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [NSObject cancelPreviousPerformRequestsWithTarget:self 
              selector:@selector(request:) 
              object:priorSearchText]; 
    [priorSearchText release], priorSearchText = [searchText retain]; 
    if (YES /* ...or whatever validity test you want to apply */) 
    [self performSelector:@selector(request:) 
       withObject:searchText 
       afterDelay:1.5]; 
} 

Non credo che abbia mai usato cancelPreviousPerformRequestsWithTarget: ... per davvero, quindi non so se nasconde delle sorprese. Se hai problemi, aggiungi NSLogs, cerca le ricerche ritardate che non vengono annullate quando dovrebbero.

+0

come si implementa la prima opzione con NSString? puoi scrivere un esempio di codice per favore? – Piero

+0

ok, scriverò qualcosa. Non è garantito che funzioni senza errori, dal momento che non ho provato questo approccio nel codice reale. – rgeorge

+0

cosa sta facendo questa linea? [self request: searchDelayer.userInfo]; ? –

0

Sposta questa linea: [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; dal vostro metodo di textDidChange e metterlo nel testo ha fatto iniziare metodo di modifica: - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar

+0

ma se aggiungo quella linea in questo metodo: - (void) searchBarTextDidBeginEditing: (UISearchBar *) searchBar qui non c'è l'argomento searchText, come posso farlo ... – Piero