Estoy usando el UISearchBar (pero no la SearchDisplayController que típicamente se utiliza en conjunción) y me gustaría despedir el teclado cuando se pulsa el botón «X».

He seguido TomSwift sugerencia en conseguir que se llama cuando la ‘X’ es aprovechado y que funciona muy bien. Pero la dimisión de primera respuesta desde el campo de texto y también la invocación en el UISearchBar instancia, ambos con resignFirstResponder, no hará que el teclado.

Hay una manera de deshacerse del teclado cuando el usuario ha aprovechado el botón X?

Aquí es lo que hice para obtener la ‘Clara’ notificar:

- (void)viewDidLoad:
{
    for (UIView* v in searchBar.subviews)
    {
        if ( [v isKindOfClass: [UITextField class]] )
        {
            UITextField *tf = (UITextField *)v;
            tf.delegate = self;
            break;
        }
    }    
}

Entonces tengo mi clase de instalación para la implementación tanto de UISearchBarDelegate y UITextFieldDelegate.

Tener la clase de servir como el textfield delegado me permite hacer esta llamada:

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
     [textField resignFirstResponder];
     [self.searchBar resignFirstResponder];
     return YES;
}

He intentado todo lo que puedo pensar. La última cosa que estoy tratando de encontrar una manera de emitir el ‘searchBarCancelButtonClicked’ que UISearchDelegate invocará en mi clase de Controlador, pero no estoy seguro de cómo podría hacer esto desde el UISearchBar no parece tener cualquiera de los métodos directos para invocar con este nombre.

  • ¿Puede explicar brevemente cómo llegó TomSwift propuesta de trabajo? No pude hacerlo funcionar en mi aplicación.
  • pregunta modificada para mostrar llegué a la clase para servir como un TextField delegado.

13 Comentarios

  1. 2

    Actualización:

    Bien, esto es un total hack pero yo era capaz de hacer que funcione. Básicamente el código invoca el controlador para el botón cancelar. Para hacer que funcione he tenido que invocar el selector con un retraso, y no estoy seguro de por qué esto tenía que ser. También, tuve que escribir un descriptor de acceso para el botón cancelar, tal y como hizo en el campo de texto.

    De nuevo, esto es un total hack. No estoy seguro de que me gustaría hacerlo yo mismo en una aplicación.

    //this in the context of the search bar
    - (UIButton*) cancelButton
    {
        for (UIView* v in self.subviews)
        {
            if ( [v isKindOfClass: [UIButton class]] )
                return (UIButton*)v;
        }
    
        return nil;
    }
    
    //this is the textField delegate callback
    - (BOOL)textFieldShouldClear:(UITextField *)textField
    {
        [textField resignFirstResponder];
    
        UIButton* cb = _searchBar.cancelButton;
    
        NSObject* target = [[cb allTargets] anyObject];
    
        NSArray* actions = [cb actionsForTarget: target forControlEvent:UIControlEventTouchUpInside];
    
        NSString* selectorName = [actions  objectAtIndex:0];
    
        SEL selector = NSSelectorFromString( selectorName );
    
        [target performSelector: selector withObject: cb afterDelay: 0.1];
    
        return YES;
    }

    Original respuesta:

    ¿Cómo se puede conseguir la clara botón » X » para mostrar en primer lugar? En mi caso de prueba no veo que mostrar…

    Tratar de hacer un resignFirstResponder en la barra de búsquedas, no el textField.

    • He añadido el UISearchBar con Interface Builder y el botón X que aparece automáticamente después de que he entrado en un carácter en la Barra de Búsqueda en el campo de texto. Traté de renunciar tanto a la barra de búsquedas (almacenado en el Controlador de clase) y textfield. No hubo suerte
    • Bueno, sí, yo estaba siendo tonto. Tengo que trabajar. No sé por qué es, no se desestima, sin embargo.
    • Justin – déjeme saber si mi respuesta actualizada funciona para usted.
    • Oh, es el retraso que se parece a hacerlo. Con todas las de la piratería, decidí que tratando de corto circuito el SDK dolorosa y se fue con la adición del botón Cancelar. Voy a tener que hacerlo de la manera que el SDK de la intención.
  2. 71

    Toms respuesta me puso a pensar. Si es que la barra de búsqueda que aún no es el firstResponder cuando el usuario hace clic en el botón borrar, sólo podemos esperar que sea y, a continuación, resignFirstResponder; es decir, a lo largo de las líneas de:

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
      [self performFilteringBySearchText: searchText]; //or whatever
    
      //The user clicked the [X] button or otherwise cleared the text.
      if([searchText length] == 0) {
        [searchBar performSelector: @selector(resignFirstResponder) 
                        withObject: nil 
                        afterDelay: 0.1];
      }
    }

    Funciona como un encanto, y menos chapucero de Tom en mi humilde opinión.

    • La salsa impresionante! Un contador de solución intuitiva, pero estoy, no obstante, utilizando fuerte y con orgullo. Gracias
    • El uso de GCD: dispatch_async(dispatch_get_main_queue(), ^(void){ [auto.barra de búsquedas resignFirstResponder]; });
    • Después de mucho buscar. Su código está trabajando para mí.. muchas Gracias!!!!!
    • ¿Qué sucede cuando el usuario pulsa el botón de borrar ? en caso de que la longitud de la buscartexto sería 0
    • Sinceramente, no lo que sucede en eliminar. Creo que en ese caso el texto de búsqueda debe ser aclarado, y el teclado desaparecer. No es esto lo que todos quieren?
    • Estoy confundido aunque la barra de búsquedas.endEditing(true) trabaja en hacer/botón de búsqueda y el botón cancelar, pero no en (X). Por qué ? nadie
    • Creo que hay algún tipo de condición de carrera entre varias partes de la interfaz de usuario código que maneja el teclado en pantalla. Supongo que en la tramitación en el botón cerrar UIKit quiere hacer que la barra de búsquedas de la firstResponder, lo que hace que la beyboard visisble (ya que es un evento que aparece ahí). Hecho/de Búsqueda, por otro lado, en términos generales, no activar la barra de búsqueda. Dicho esto debo añadir que esto es discutible la especulación.

  3. 6

    Esto funciona:

    [searchBar performSelector:@selector(resignFirstResponder) withObject:nil afterDelay:0.1];
  4. 5

    Actualizado para SWIFT 3:

    Supongamos que el usuario ha introducido una cadena en searchfield y hace clic en x el siguiente código funciona para ocultar el teclado cuando x se pulsa

    `

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
    {
                if searchBar.text == nil || searchBar.text == ""
                {
                    searchBar.perform(#selector(self.resignFirstResponder), with: nil, afterDelay: 0.1)
                }
     }

    `

  5. 3

    Swift 2 versión:

    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
            //The user clicked the [X] button or otherwise cleared the text.
            if (searchText.characters.count == 0) {
                searchBar.performSelector("resignFirstResponder", withObject: nil, afterDelay: 0.1)
            }
        }
  6. 2

    Puede resignFirstResponder con el clic del Botón cancelar como.

    - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
    
    {
    
        SearchBar.showsCancelButton =NO;
    
    }
    
    
    - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
    {
    
        [SearchBar resignFirstResponder];
    
    
    }
    • Pero si usted desea hacer esto haga clic en el Botón x,entonces usted tiene que tomar un botón y agregue la imagen de x como a ella.a continuación, al hacer clic en este Botón, se puede renunciar a la FirstResponder
    • Esto no es exactamente lo que está buscando. Él quiere quitar el teclado cuando el claro texto del botón es pulsado.
    • Sí Tozer yo sé lo que él está buscando ,por lo que acabo de ver el comentario de abajo que me han dado.Él tiene que tomar su propio botón para hacer que en lugar de botón borrar.
    • No hay ningún botón Cancelar en absoluto – sólo la acción Clara desde el botón X y no quiero agregar otros botones.
    • No hay botón cancelar que puede estar oculta o muestra y el botón borrar en la barra de búsqueda en el campo como bien bro.
    • Esta es una buena alternativa, creo.

  7. 1

    Tratar de evitar

    - (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar

    método en el código podemos resolver este

  8. 1

    He utilizado una combinación de @radiospiel la respuesta y también la respuesta que @Tozar vinculado a:

    @interface SearchViewController : UIViewController <UISearchBarDelegate> {
        //all of our ivar declarations go here...
        BOOL shouldBeginEditing;
        ....
    }
    
    ...
    @end
    
    @implementation SearchViewController
    ...
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
            ...
            shouldBeginEditing = YES;
        }
    }
    ...
    
    - (void) searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
        //TODO - dynamically update the search results here, if we choose to do that.
    
        if (![searchBar isFirstResponder]) {
            //The user clicked the [X] button while the keyboard was hidden
            shouldBeginEditing = NO;
        }
        else if ([searchText length] == 0) {
            //The user clicked the [X] button or otherwise cleared the text.
            [theSearchBar performSelector: @selector(resignFirstResponder)
                            withObject: nil
                            afterDelay: 0.1];
        }
    }
    
    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar {
        //reset the shouldBeginEditing BOOL ivar to YES, but first take its value and use it to return it from the method call
        BOOL boolToReturn = shouldBeginEditing;
        shouldBeginEditing = YES;
        return boolToReturn;
    }
    @end
  9. 1

    No debería de interfaz de usuario los cambios se hagan en el hilo principal en lugar de utilizar performselector:WithObject:afterDelay:?

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        if (searchText.length == 0) {
            [searchBar performSelectorOnMainThread:@selector(resignFirstResponder) withObject:nil waitUntilDone:NO];
        }
    }
  10. 0

    EDICIÓN: en Realidad, la de abajo se rompe el delegado que está conectado a UISearchBar. Sólo subclase UISearchBar y sobrescribir el UITextField método de Delegado.

    ===========================

    Tenía que hacer esto para obtener acceso a la UITextView

    for (UIButton* v in [self.searchBar.subviews[0] subviews])
    {
        if ( [v isKindOfClass: [UITextField class]] )
        {
            UITextField *tf = (UITextField *)v;
            tf.delegate = self;
            break;
        }
    }
  11. 0

    De crédito a Maxhs original respuesta :
    Esto es swift 2.2 versión :
    Trabajo como un encanto para mí

    if searchBar.text == "" {
                    dispatch_async(dispatch_get_main_queue(), { 
                        self.searchBar.resignFirstResponder()
                    })
                }
  12. 0

    Otro punto de vista para el texto claro de flujo (similar a @TomSwift respuesta pero la más clara para mí y menos complicado). Además, tengo que ocultar botón Cancelar después de la salida de la barra de búsqueda, implementar live search (después de cada símbolo) y la cubierta de la mesa antes de que el usuario complete la búsqueda.

    //self.searchHoverView can cover table view
    //performSearchWithSearchBar: method for performing search
    
    #pragma mark - UISearchBarDelegate
    
    - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
        [searchBar setShowsCancelButton:YES animated:YES];
        self.searchHoverView.hidden = NO;
    }
    
    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
        if (searchText.length) {
            [self performSearchWithSearchBar:searchBar];
        } else {
            UIButton *button;
            for (UIView *subView in [searchBar subviews]) {
                for (UIView *view in [subView subviews]) {
                    if ([view isKindOfClass:[UIButton class]]) {
                        button = (UIButton *)view;
                        break;
                    }
                }
            }
    
            if (button) {
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [button sendActionsForControlEvents:UIControlEventTouchUpInside];
                });
            }
        }
    }
    
    - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
        self.searchBar.text = nil;
    
        [self.searchBar setShowsCancelButton:NO animated:YES];
        [self.searchBar resignFirstResponder];
    
        self.searchHoverView.hidden = YES;
    }

Dejar respuesta

Please enter your comment!
Please enter your name here