¿Qué es un UISearchController?
Es un componente que nos ayuda a mostrar de una manera adecuada los resultados de busqueda de un usuario.
Implementando un UISearchController
Primero vamos a declarar un ViewController donde mostraremos los resultados de busqueda al cuál llamaremos ResultViewController, para mi ejemplo cree un ViewController en el storyboard y le agrege un indetificador para poder utilizarlo
// Usamos lazy para cargarlo en memoria cuando lo necesitemos
lazy var resultViewController: UIViewController = {
// Llamamos al Storyboard donde esta mi ViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Instancio al ViewController usando el identificador que le asigne
let resultView = storyboard.instantiateViewController(withIdentifier: "ResultsViewController")
/* Valido si la instancia es de la clase ResultsViewController la cual
usaré para mostrar los resultados */
guard let resultViewController = resultView as? ResultsViewController else {
fatalError("Problems with viewController")
}
return resultViewController
}()
Luego voy a crear una instancia del UISearchController y realizar la personalizacion que deseamos
lazy var searchController: UISearchController = {
/* Creamos la instancia y le asignamos el ViewController donde vamos a mostrar
los resultados (el ResultViewController lo creamos anteriormente) */
let searchController = UISearchController(searchResultsController: resultViewController)
// Vamos a mostra una vista oscura con alpha al momento de usar el buscador
searchController.dimsBackgroundDuringPresentation = true
// Ocultamos el NavigationBar cuando se muestra el buscador
searchController.hidesNavigationBarDuringPresentation = true
// Vamos a aplicar el delegado de la vista que usaremos resultados
searchController.searchResultsUpdater = self
return searchController
}()
Como ya tenemos nuestro SearchViewController lo asignamos a la vista donde lo queremos mostrar, recordemos que desde iOS 11, nos dan la facilidad de colocarlo en el NavigationBar
override func viewDidLoad() {
super.viewDidLoad()
/* Asignamos el SearchController al ViewController que ya debe de tener un
NavigationBar implementando */
self.navigationItem.searchController = searchController
/* Con esta linea decimos que no queremos ocultar el SearchBar
cuando se realize scroll */
self.navigationItem.hidesSearchBarWhenScrolling = false
/* Definimos que el ResultViewController se muestre debajo de nuestro
NavigationBar, si colocamos el definesPresentationContext en false el
ResultViewController se mostrara en toda la pantalla. */
self.definesPresentationContext = true
}
Mostrando los resultados de busqueda
Para mostrar lo resultados de busqueda del SearchController debemos implementar el delegado que previamente habiamos implementado
searchController.searchResultsUpdater = self
extension MainViewController: UISearchResultsUpdating {
/* Este es el metodo delegado para poder obtener cada letra que se ingrese
en el SearchBar */
func updateSearchResults(for searchController: UISearchController) {
// Obtenemos el texto del SearchBar
guard let searchText = searchController.searchBar.text else {
return
}
/* Pasamos el texto a nuestro metodo *getResults y obtenemos
los datos filtrados */
let filteredResults = getResults(searchText)
/* usamos el searchController que nos da el metodo delegado del cual
obtenemos la vista donde mostramos los resultados mediente el uso de
searchResultsController, al cual le hacemos la validacion que sea del
tipo de ViewController que usaremos para mostrar los resultados. */
if let resultView = searchController.searchResultsController as? ResultsViewController {
/* el resultView.results es por donde le vamos a pasar a nuestra vista de resultado
lo resultados que filtramos previamente */
resultView.results = filteredResults
}
}
}
- El metodo getResults que usamos para obtener los datos filtrados, deberia ser tú metodo para que hage la comparación entre el texto que se ingresa en el searchBar y tu fuente de datos
Conclusión
Debemos aprovechar el ResultViewController ya que es una de las formas convenientes de mostrar los resultados de busqueda. He visto en otras ocaciones en donde se suele usar el SearchController asignandole al ResultViewController como nil y terminando usando los protocolos del SearchBar para obtener los datos ingresado por el textField del SearchBar, cosa que seria inecesaria si se saber usar el ResultViewController.
- El demo final se encuentra en Github