2010-06-16 16 views
23

derecho, para comenzar mi pregunta, aquí hay algunos Screenies del problema ya resuelto por el Spotify aplicación:botón de limpieza (x gris) Llevar a la derecha del UISearchBar cuando botón de cancelación golpeó

de Spotify Paso 1: Estándar UISearchBar no está en modo de edición.

Step 1 http://i49.tinypic.com/wbtpwi.png

de Spotify Paso 2: UISearchBar ahora en el modo de edición. Término de búsqueda ingresado. El botón Cancelar se desliza desde la derecha y aparece el botón Borrar (gris x).

Step 2 http://i45.tinypic.com/161kbvp.png

de Spotify Paso 3: botón Cancelar presionado; el teclado se desliza y la barra de búsqueda ya no se encuentra en el modo de edición. El término de búsqueda permanece y el botón gris x ahora está oculto.

Step 3 http://i46.tinypic.com/20utv9v.png

En la actualidad, el siguiente código dispara cuando mi cancelar se pulsa el botón:

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 
    [searchBar resignFirstResponder]; 
    [searchBar setShowsCancelButton:NO animated:YES]; 
} 

que se traduce en:

Mi Paso 3: barra de búsqueda ahora no en modo de edición. El botón Cancelar y el teclado se han deslizado. El término de búsqueda permanece pero también lo hace el gris x.

Problem http://i46.tinypic.com/rlm4w5.png

lo tanto, mi pregunta es la siguiente: dado que -resignFirstResponder (y -endEditing:, FYI) hace no ocultar el botón de x gris cuando una barra de búsqueda ha tenido texto introducido en ella, ¿cómo se puede ocultar que ?

Gracias de nuevo, amigos.

Respuesta

29

El problema es que UISearchBar no expone su campo de texto y administra las propiedades en el campo de texto. Algunas veces, los valores de las propiedades no son lo que quieres.

Por ejemplo, en mi propia aplicación, quería que el estilo del teclado de mi barra de búsqueda utilizara el estilo de alerta transparente.

Mi solución fue recorrer las subvistas de la barra de búsqueda hasta que encuentre el campo de texto. Entonces debería poder establecer la propiedad clearButtonMode, usando algo como UITextFieldViewModeWhileEditing como parámetro.

Esto debería hacer que el botón de borrar solo se muestre mientras se edita el campo de texto.

Quiere hacer esto en viewDidLoad o algo temprano, por lo que se establece antes de comenzar a usarlo (pero después de que se inicializa la barra de búsqueda).

for (UIView *subview in searchBar.subviews) 
{ 
    if ([subview conformsToProtocol:@protocol(UITextInputTraits)]) 
    { 
     [(UITextField *)subview setClearButtonMode:UITextFieldViewModeWhileEditing]; 
    } 
} 
+1

Saludos Jasarien, esto parece ser exactamente lo Necesito. Lamentablemente, me encuentro con un error con '[subview conformsToProtocol: UITextInputTraits]' que dice: 'expresión esperada antes de 'UITextInputTraits''. ¿Debo importar o conformarme a algo? –

+2

¡Malo! Lo siento. Debes hacer '[subview conformsToProtocol: @protocol (UITextInputTraits)] ' – Jasarien

+0

¡Eso es todo! Eres un genio. Gracias amigo. –

3

Para ampliar la respuesta Jadariens si no desea en la X gris que aparece es necesario utilizar la siguiente

for (UIView *subview in searchBar.subviews) 
{ 
    if ([subview conformsToProtocol:@protocol(UITextInputTraits)]) 
    { 
     [(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever]; 
    } 
} 
6

Parece que iOS 7 cambia la vista de jerarquía de UISearchBar, y el cuadro de texto es más profundo en la vista (La solución anterior no funcionó para mí). Sin embargo, la modificación de la solución anterior para recorrer toda la jerarquía funciona:

[self configureSearchBarView:[self searchBar]]; 

- (void)configureSearchBarView:(UIView*)view { 
    for (UIView *subview in [view subviews]){ 
     [self configureSearchBarView:subview]; 
    } 
    if ([view conformsToProtocol:@protocol(UITextInputTraits)]) { 
     [(UITextField *)view setClearButtonMode:UITextFieldViewModeWhileEditing]; 
    } 
} 
+0

Esto podría convertirse fácilmente en una Categoría en UISearchBar para permitir la reutilización. – ABeanSits

+3

Parece que provoca un bloqueo, aparentemente hay más de una vista que se ajusta a 'UITextInputTraits' y esa vista no puede responder a' setClearButtonMode'. – Mackey18

+0

Para evitar el bloqueo lo cambié a esto: 'para la subvista (UIView * en [self.searchDisplayController.searchBar subviews]) {[self configureSearchBarView: subview];}' seguido por el método 'configureSearchBarView: (UIView *) view' . Parece que en mi caso fue la barra de búsqueda misma la que causó el bloqueo. – Mackey18

6

estoy construyendo en las respuestas anteriores, porque empecé a ver accidentes en IOS 7.1 a menos que hiciera el siguiente cambio. Agregué una llamada adicional al respondsToSelector para cada vista para asegurarme de que se puede llamar al setClearButtonMode:. Observé una instancia de UISearchBar que se transfirió, que parece ajustarse al protocolo UITextInputTraits pero no tiene el selector setClearButtonMode:, por lo que se produjo un bloqueo. También se pasa una instancia de UISearchBarTextField y es el objeto real al que se debe llamar al setClearButtonMode:.

 
- (void)removeClearButtonFromView:(UIView *)view 
{ 
    if (!view) 
    { 
     return; 
    } 

    for (UIView *subview in view.subviews) 
    { 
     [self removeClearButtonFromView:subview]; 
    } 

    if ([view conformsToProtocol:@protocol(UITextInputTraits)]) 
    { 
     UITextField *textView = (UITextField *)view; 
     if ([textView respondsToSelector:@selector(setClearButtonMode:)]) 
     { 
      [textView setClearButtonMode:UITextFieldViewModeNever]; 
     } 
    } 
} 
+0

¡La mejor solución! Gracias. –

+0

De hecho, este funciona muy bien con iOS 7. –

4

Una mejor manera de hacer esto en iOS7 es:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setClearButtonMode:UITextFieldViewModeWhileEditing];

0

La suya es una categoría que escribí que hace esto

Categoría

@implementation UISearchBar (Additions) 

- (void)setClearButtonMode:(UITextFieldViewMode)viewMode { 
    UITextField *textField = [self findTextFieldInView:self]; 
    [textField setClearButtonMode:viewMode]; 
} 

- (UITextField *)findTextFieldInView:(UIView *)view { 

    for (UIView *subview in view.subviews) { 

     if ([subview isKindOfClass:[UITextField class]] || 
      [subview.class isSubclassOfClass:[UITextField class]]) { 

      return (UITextField *)subview; 
     } 

     UITextField *textField = [self findTextFieldInView:subview]; 

     if (textField) { 
      return textField; 
     } 
    } 

    return nil; 
} 

@end 

Uso

[searchBar setClearButtonMode:UITextFieldViewModeWhileEditing]; 
4

que necesita para obtener el campo de texto de la barra de búsqueda

UITextField *textField = [searchBar valueForKey:@"_searchField"]; 
textField.clearButtonMode = UITextFieldViewModeNever; 

uso en - (void) searchBarTextDidBeginEditing: (UISearchBar *) Método de barra de búsqueda.

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 
{ 

UITextField *textField = [searchBar valueForKey:@"_searchField"]; 
textField.clearButtonMode = UITextFieldViewModeNever; 


} 
0

hay una manera mejor que cualquiera de las respuestas aquí, y usted no tiene que utilizar las API privadas o subvistas transversales para hacerlo.

UISearchBar tiene una API incorporado para hacer esto:

[UISearchBar setImage:forSearchBarIcon:state]

La clave icono SearchBar desea es UISearchBarIconClear, y desea que el estado UIControlStateNormal. Luego, dale una imagen clara para la imagen, y listo.

Por lo tanto, debe tener este aspecto:

[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal]; 
0

Para el icono (x) en la barra de búsqueda. Puede usar el método de delegado a continuación.

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 
{ 
    searchBar.showsCancelButton = YES; 
} 
0
for (UIView *subview in _search_bar.subviews) 
{ 
    NSLog(@"%@",subview.subviews); 

    for (UIView *subview11 in subview.subviews) 
    { 
     if ([subview11 conformsToProtocol:@protocol(UITextInputTraits)]) 
     { 
      [(UITextField *)subview11 setClearButtonMode:UITextFieldViewModeNever]; 
     } 
    } 

} 
1

respuesta aceptada no funciona en iOS7 +, aquí es la versión modificada como una extensión Swift

extension UIView { 
    class func removeClearButton(svs: [UIView]) { 
     for sv in svs { 
      if let tv = sv as? UITextField where sv.conformsToProtocol(UITextInputTraits) { 
       tv.clearButtonMode = .Never 
       return 
      } else { 
       UIView.removeClearButton(sv.subviews) 
      } 
     } 
    } 
} 

Uso

UIView.removeClearButton(searchBar.subviews) 
Cuestiones relacionadas