UISearchController solo actualiza en el button de búsqueda haga clic

Tengo un UISearchController que está configurado para search una gran variedad de datos. Como tal, cuando estoy escribiendo en la barra de búsqueda, me lleva mucho time escribir mi búsqueda. Realiza la comparación de búsqueda con cada input de caracteres en el campo de búsqueda, que es muy lento.

Me pregunto cómo solucionar esto. Mis pensamientos son:

  1. solo realice la búsqueda después de que el usuario termine de escribir y presione el button de búsqueda
  2. realice la búsqueda en un hilo de background, liberando el hilo principal para la input del keyboard

Me gustaría usar el método 1, pero parece que no puedo entender cómo hacerlo con el nuevo UISearchController.

A continuación se muestra mi código de proyecto relevante:

class AirportSearchTBVC: UITableViewController, UISearchResultsUpdating{ var airportData = [Dictionary<String, String>]() var filtenetworkingData = [Dictionary<String, String>]() var searchController = UISearchController() override func viewDidLoad() { super.viewDidLoad() searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false searchController.searchBar.sizeToFit() tableView.tableHeaderView = searchController.searchBar definesPresentationContext = true searchController.hidesNavigationBarDuringPresentation = false self.tableView.reloadData() } func updateSearchResultsForSearchController(searchController: UISearchController) { filtenetworkingData = [] let searchPnetworkingicate = NSPnetworkingicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!) let array = (airportData as NSArray).filtenetworkingArrayUsingPnetworkingicate(searchPnetworkingicate) filtenetworkingData = array as! [Dictionary<String, String>] self.tableView.reloadData() } 

Pregunta adicional Si busco una cadena, no parece devolver ningún resultado si la cadena no coincide perfectamente. Por ejemplo: "orida" no encuentra "Florida". ¿No se supone que mi pnetworkingicado de búsqueda debe encontrar esto usando CONTAINS?

Actualización Este código casi funciona, pero básicamente arroja un montón de cosas en el hilo de background y luego aparece a través de él. El keyboard está animado ahora, pero parece fallar si cambio las cosas rápidamente en el campo de text mientras descarta y vuelve a ingresar en la barra de búsqueda …

 func updateSearchResultsForSearchController(searchController: UISearchController) { appDel.backgroundThread(background: { self.filtenetworkingData.removeAll(keepCapacity: false) let searchPnetworkingicate = NSPnetworkingicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!) let array = (self.airportData as NSArray).filtenetworkingArrayUsingPnetworkingicate(searchPnetworkingicate) self.filtenetworkingData = array as! [Dictionary<String, String>] }, completion: { dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadData() } }); } 

Actualización 2 Después de jugar un poco con él, pude conseguir que funcione bastante decentemente por ambos esperando una longitud searchBar.text> = 3 caracteres, así como asegurándose de que el recuento de caracteres no cambió dentro de 1 segundo de updateSearchResultsForSearchController : siendo llamado. La combinación de estos, así como la integración de un button de búsqueda ejecutar el command debería resolver mi problema.

 func updateSearchResultsForSearchController(searchController: UISearchController) { let startCount = searchController.searchBar.text!.length delay(1) { if searchController.searchBar.text!.length >= 3 && searchController.searchBar.text!.length == startCount{ self.view.addSubview(self.progressHud) self.appDel.backgroundThread(background: { self.filtenetworkingData.removeAll(keepCapacity: false) let searchPnetworkingicate = NSPnetworkingicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!) let array = (self.airportData as NSArray).filtenetworkingArrayUsingPnetworkingicate(searchPnetworkingicate) self.filtenetworkingData = array as! [Dictionary<String, String>] }, completion: { dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadData() self.progressHud.removeFromSuperview() } }); } } } func delay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure) } 

Puede usar el método de delegado searchBarSearchButtonPressed: para supervisar cuando se presiona el button de búsqueda. Establezca un indicador cuando se ejecute este método delegado y luego, en su método searchBarTextDidChange: puede marcar esta bandera para ver si debe ejecutar la búsqueda. Por supuesto, esto solo searchá después de que el usuario presiona la búsqueda, y la mayoría de las personas esperan ver que algo sucede mientras escriben.

Si desea realizar solo la búsqueda cuando el usuario hace clic en el button "Buscar", que parece sensato y razonable para un set de datos de acceso más grande y más lento, puede hacerlo de la siguiente manera:

 class AirportSearchTBVC: UITableViewController, UISearchResultsUpdating{ var airportData = [Dictionary<String, String>]() var filtenetworkingData = [Dictionary<String, String>]() var searchController = UISearchController() override func viewDidLoad() { super.viewDidLoad() searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.searchBar.delegate = self searchController.dimsBackgroundDuringPresentation = false searchController.searchBar.sizeToFit() tableView.tableHeaderView = searchController.searchBar definesPresentationContext = true searchController.hidesNavigationBarDuringPresentation = false self.tableView.reloadData() } func searchBarSearchButtonClicked(searchBar: UISearchBar) { filtenetworkingData = [] let searchPnetworkingicate = NSPnetworkingicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!) let array = (airportData as NSArray).filtenetworkingArrayUsingPnetworkingicate(searchPnetworkingicate) filtenetworkingData = array as! [Dictionary<String, String>] self.tableView.reloadData() } func updateSearchResultsForSearchController(searchController: UISearchController) { } 

Las diferencias key son establecer el searchController.searchBar.delegate = self, y poner su código de búsqueda en la function searchBarSearchButtonClicked en lugar de updateSearchResultsForSearchController, que ahora no debería hacer nada. Pido disculpas por cualquier error, probé este código usando Xcode v7.0.1 Objective-C, y luego transpuse los cambios.