2012-03-10 13 views
17

estoy en busca implementar un UISearchbar que recuperar información desde una URL, y con el método por defecto:UISearchBar detectar cuando el tipo de usuario y una parada No buscar inmediatamente para detectar pausa

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

i puede detectar inmediatamente cuando el texto cambia y realiza la búsqueda de url, pero de esta manera, el tipo de texto es lento porque el iPhone está buscando la url, entonces quiero comenzar a buscar la url cuando el usuario deja de escribir por un segundo, entonces quiero detectar la pausa de la escritura para actualizar la vista de tabla recuperando la información por la url. he encontrado un post anterior de esta solicitud y he intentado una solución que para mí no trabajo:

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

de esta manera cuando estoy escribiendo el método de la petición no se conoce, pero cuando dejo de escribir es llamado para cada caracter que escribo, entonces es el mismo del metodo por defecto, ¿me equivoco? o la implementación no es correcta?

Respuesta

24

Parece que la solución proporcionada no está funcionando porque el argumento "searchText" a cancelPreviousPerformRequestsWithTarget:selector:object: no coincide con el argumento "searchText" de la llamada anterior al performSelector:withObject:afterDelay:; por lo que las búsquedas diferidas se ponen en cola cada cambio de texto, y nunca se cancelan.

Puede utilizar NSTimer para retrasar la invocación de su búsqueda, y cancelar el temporizador siempre que el texto cambie: otorgue a su objeto una propiedad 0 campo NSTimer; en searchBar:textDidChange: cancelar cualquier temporizador existente, luego crear y programar uno nuevo. El objetivo del temporizador debe llamar a su método de búsqueda.

Algo así como (la parte superior de la cabeza):

// 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 
} 

Algunos programadores podrían ser menos atrevidas acerca de referencias débiles de lo que estoy de estar aquí.

[editado añadir:]

de cómo podría hacerlo si se fijan en el uso de cancelPreviousPerformRequestsWithTarget aquí ...:

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

No creo que he usado cancelPreviousPerformRequestsWithTarget: ... de verdad, así que no sé si esconde sorpresas. Si tiene problemas, agregue NSLogs y busque que las búsquedas retrasadas no se cancelen cuando deberían.

+0

cómo se implementa la primera opción con el NSString? ¿Puedes escribir un ejemplo de código, por favor? – Piero

+0

bien, escribiré algo. Sin embargo, no garantizamos que funcione sin errores, ya que no he probado este enfoque en código real. – rgeorge

+0

¿Qué está haciendo esta línea? [solicitud propia: searchDelayer.userInfo]; ? –

0

Mover esta línea: [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; de su método textDidChange y ponerlo en el texto comenzó método de edición: - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar

+0

pero si agrego esa línea en este método: - (void) searchBarTextDidBeginEditing: (UISearchBar *) searchBar aquí no existe el argumento searchText, cómo puedo hacerlo ... – Piero

Cuestiones relacionadas