2010-11-08 7 views

Respuesta

6

El UISearchBar no tiene un método delegado para este evento. Casi puede obtener lo que desea implementando el método textDidChange: del delegado de devolución de llamada y buscando una cadena vacía.

No lo recomiendo, pero hay otra manera posible. El UISearchBar está compuesto por un UITextField, que tiene un método delegado que se llama cuando el usuario toca el botón borrar (textFieldShouldClear:). Usted puede obtener el UITextField por la que atraviesa el UISearchBar 's vistas secundarias:

(esto es, en el contexto de una clase derivada UISearchBar)

- (UIView*) textField 
{ 
    for (UIView* v in self.subviews) 
    { 
     if ([v isKindOfClass: [UITextField class]]) 
      return v; 
    } 

    return nil; 
} 

desde aquí, podría reasignar el delegado UITextField a su propia implementación, teniendo cuidado de reenviar las llamadas de delegado al antiguo delegado. De esta manera podría interceptar textFieldShouldClear:. O si resulta que el UISearchBar es el delegado para el UITextField que contiene, podría swizzlear la llamada a textFieldShouldClear: ... No es ideal, claro, pero técnicamente factible.

+0

¿Por qué no recomiendan la aplicación de la textDidChange y la comprobación de una cadena vacía? –

+0

Creo que esta sería una buena forma de hacerlo.Pero no es exactamente lo que está pidiendo, ya que el texto puede convertirse en una cadena vacía en otras formas que haciendo clic en la 'x'. Al igual que el retroceso ... Entonces, si quiere que le avisemos siempre que haga clic en la 'x', esto dará como resultado un falso positivo. – TomSwift

+0

Esto no va a funcionar con ios 8 más –

2

Tuve el mismo problema y resolví este problema usando esta función.

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    // This method has been called when u enter some text on search or Cancel the search. 
    if([searchText isEqualToString:@""] || searchText==nil) { 
     // Nothing to search, empty result. 

     [UIView animateWithDuration:0.2 animations:^ { 
     //Reposition search bar 
     [_searchBar setFrame:CGRectMake(230, 26, 43, 44)]; 
     [_searchBar setNeedsLayout]; 
     }]; 
    } 
} 
0

Aquí está la solución "Method Swizzling".

  1. Crear una nueva categoría de UISearchBar. Esta categoría crea un nuevo método y método swizzle entre -(BOOL)textFieldShouldClear:(UITextField *)textField; y -(BOOL)jbm_textFieldShouldClear:(UITextField *)textField en tiempo de ejecución.
  2. personalizar un nuevo Protocolo de UISearchBarDelegate con el fin de añadir un nuevo método - (void)searchBarClearButtonClicked:(id)sender;

UISearchBar + JMBTextFieldControl.h

@protocol UISearchBarWithClearButtonDelegate <UISearchBarDelegate> 
    @optional 
    - (void)searchBarClearButtonClicked:(id)sender; 
    @end 

    @interface UISearchBar (JMBTextFieldControl) 
    @end 

UISearchBar + JMBTextFieldControl.m

#import "UISearchBar+JMBTextFieldControl.h" 
    #import <objc/runtime.h> 

    @implementation NSObject (Swizzling) 

    + (void)brc_swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector 
    { 
     Method origMethod = class_getInstanceMethod(self, origSelector); 
     Method newMethod = class_getInstanceMethod(self, newSelector); 

     if(class_addMethod(self, origSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) 
      class_replaceMethod(self, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
     else 
      method_exchangeImplementations(origMethod, newMethod); 
    } 
    @end 

    @implementation UISearchBar (JMBTextFieldControl) 

    + (void)load { 
     [self brc_swizzleMethod:@selector(textFieldShouldClear:) withMethod:@selector(jbm_textFieldShouldClear:)]; 
    } 

    - (id<UISearchBarWithClearButtonDelegate>)jbm_customDelegate { 
     if([[self delegate] conformsToProtocol:@protocol(UISearchBarWithClearButtonDelegate)]) 
      return (id<UISearchBarWithClearButtonDelegate>)[self delegate]; 
     else 
      return nil; 
    } 

    - (BOOL)jbm_textFieldShouldClear:(UITextField *)textField 
    { 
     if ([[self jbm_customDelegate] respondsToSelector:@selector(searchBarClearButtonClicked:)]) 
      [[self jbm_customDelegate] searchBarClearButtonClicked:self]; 

     return [self jbm_textFieldShouldClear:textField]; 
    } 

    @end 

Referencia

  1. de Dave DeLong - How to add a method to an existing protocol in Cocoa?

  2. Nikolay Vlasov - CCBottomRefreshControl

Cuestiones relacionadas