Al asignar foco a través de becomeFirstResponder a UISearchController's UISearchBar, el keyboard no aparece

He pasado bastante time buscando en línea y hablando con otros desarrolladores sobre este problema sin éxito. El problema exacto se describe en esta publicación SO ( Focus on the UISearchBar pero el keyboard no aparece ), aunque tiene muchos años.

Hace poco cambié de usar el UISearchDisplayController en desuso y el UISearchBar en IB, y cambié a UISearchController a través del código para iOS8.

Sin embargo, el problema que tengo es que el foco se asigna correctamente (se puede saber porque el button cancelar se anima a la derecha de la barra de búsqueda después de que se carga la vista), sin embargo, el keyboard no aparece.

Aquí está el código que tengo.

.marido

@property (nonatomic, strong) UISearchController *searchController; 

.metro

 - (void)viewDidLoad { [super viewDidLoad]; ... [self initializeSearchController]; .... } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.searchController setActive:YES]; [self.searchController.searchBar becomeFirstResponder]; } - (void)initializeSearchController { self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; self.searchController.searchResultsUpdater = self; self.searchController.dimsBackgroundDuringPresentation = NO; self.searchController.delegate = self; self.searchController.searchBar.delegate = self; [self.searchController.searchBar sizeToFit]; [self.tableView setTableHeaderView:self.searchController.searchBar]; self.definesPresentationContext = YES; } 

Las cosas que he intentado hasta ahora.

  • He intentado llamar a becomeFirstResponder con una demora de 0.2 segundos, como se sugiere en otra publicación de SO.

  • He establecido un punto de interrupción en viewDidAppear, y he verificado que tanto self.searchController como self.searchController.searchBar son objects válidos, ni nil.

  • Intenté conformarme con el UISearchControllerDelegate y usé el siguiente fragment de código

aquí:

 - (void)didPresentSearchController:(UISearchController *)searchController { //no matter what code I put in here to becomeFirstResponder, it doesn't //matter because this is never called, despite setting the //self.searchController.delegate = self AND //self.searchController.searchBar.delegate = self. } 
  • He creado una nueva vista desde cero en los guiones charts, y he seguido a esa en su lugar, para asegurarme de que no tenía un viejo reverso de la barra de búsqueda en mi opinión. Esto no funcionó bien.

  • Solo probé esto en un dispositivo real (iPhone 6), y no es un problema de simulador que no muestre el keyboard.

Estoy sin ideas, y he visto todas las preguntas y respuestas relacionadas con esta la web. Nada funciona.

Para aclarar nuevamente lo que está sucediendo, el searchBar se convierte correctamente en el primer respondedor, el button de cancelar a la derecha de él anima en la pantalla probando esto, pero el keyboard no aparece y el cursor no parpadea en el searchBar.

Tu código se ve bien. Lo que está describiendo no es un comportamiento normal. Lo primero que puede hacer es crear un nuevo proyecto con solo la funcionalidad UISearchController y ver cómo va. Puedes editar tu pregunta con él para que podamos tener una mejor vista.

Hay un buen ejemplo de cómo implementar UISearchController aquí: Sample-UISearchController

Agregando:

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.searchController.searchBar becomeFirstResponder]; } 

a MasterViewController_TableResults.m dio los resultados esperados y el keyboard apareció en el lanzamiento en un iPad y iPhone con iOS 8.3.

Puede repasar ese proyecto y ver lo que hizo de manera diferente,

Editar:

Aparentemente si se [self.searchController setActive:YES] antes de becomeFirstResponder el keyboard no se mostrará. Me pregunto si eso es un error o no.

Tenía el mismo problema molesto. Podría pensar que al establecer el SearchController como activo, ambos presentarían el controller de búsqueda y el keyboard. Desafortunadamente, solo hace la primera parte.

Mi solución

  • en viewDidAppear activa el controller de búsqueda:

     override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) resultSearchController.active = true } 
  • una vez que está activo, en didPresentSearchController hacer como primer respondedor

     func didPresentSearchController(searchController: UISearchController) { searchController.searchBar.becomeFirstResponder() } 

Swift 3.0 (iOS 10) solución de trabajo:

  override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) searchController.isActive = true DispatchQueue.main.async { [unowned self] in self.searchController.searchBar.becomeFirstResponder() } } 

En iOS 9, he encontrado que es suficiente para retrasar becomeFirstResponder() en el próximo ciclo de ejecución:

 func focusSearchField() { searchController?.active = true // skipping to the next run loop is requinetworking, otherwise the keyboard does not appear dispatch_async(dispatch_get_main_queue(), { [weak self] in self?.searchController?.searchBar.becomeFirstResponder() }) } 

En iOS 10, tuve que ejecutar el código en el método de delegado en el hilo principal. Primero, establezco el activo en YES en viewDidAppear,

 -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [self.searchController setActive:YES]; } 

y luego en el método delegado:

 - (void)didPresentSearchController:(UISearchController *)searchController { dispatch_async(dispatch_get_main_queue(), ^{ [searchController.searchBar becomeFirstResponder]; }); } 

La solución que funcionará es la siguiente:

1.Override ViewDidLayoutSubviews en el controller de vista en el que está mostrando UISearchController

2.Override ViewDidLayoutSubviews y en su interior, haga que la barra de búsqueda sea la primera respuesta.

Lo probé en iOS> 9.0

Precaución: ponga una comprobación nula antes de hacerla responder primero de la siguiente manera

 if((searchController != null)&&(searchController.SearchBar != null)) searchController.SearchBar.BecomeFirstResponder(); 

Esto se debe a que ViewDidLayoutSubviews también se ViewDidLayoutSubviews cuando se presiona el button cancelar.

Esto funcionó para mí en Xamarin.

Solución de trabajo:

No use [self.searchController setActive: YES] antes de becomeFirstResponder.

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ // [self.searchController setActive:YES]; [self.searchController.searchBar becomeFirstResponder]; }); }); } 

Tuve problemas con un UISearchBar que no mostraba el keyboard cuando estaba

 [searchBar becomeFirstResponder]; 

Al search en la networking, encontré este hilo en el website de desarrolladores de Apple que me ayudó a descubrir que el keyboard no se abrirá si no tienes una keyWindow.

La aplicación en la que trabajo hace algo como esto:

  1. Ventana A (window key)
  2. hacer algunas cosas
  3. abrir la window B (KeyWindow)
  4. hacer algunas cosas
  5. cerrar window B (renunciar a KeyWindow)

Solo tuve que hacer

 [[[[UIApplication shanetworkingApplication] windows] firstObject] makeKeyWindow]; 

después de la dimisión de la window B y no más problemas con el keyboard.

Esto también podría estar relacionado con la configuration del simulador. Simplemente deshabilita Hardware -> Teclado -> "Conectar keyboard de hardware".

Para más detalles: UISearchBar no muestra el keyboard cuando se toca

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.searchController setActive:YES]; } //and then in the delegate method: - (void)didPresentSearchController:(UISearchController *)searchController { dispatch_async(dispatch_get_main_queue(), ^{ [searchController.searchBar becomeFirstResponder]; }); } //The above works for me in addition to this I had to add: -(void)viewWillDisappear:(BOOL)animated { [searchController setActive:NO]; }