updatesearchresults tutorial searchcontroller for example custom bar ios swift uisearchcontroller

ios - tutorial - Intentando cargar la vista de un controlador de vista mientras se está desasignando... UISearchController



searchcontroller tutorial (13)

Aquí está la versión Swift que funcionó para mí (similar a la respuesta de JJH):

deinit{ if let superView = resultSearchController.view.superview { superView.removeFromSuperview() } }

Tengo un código que crea un UISearchController'' in my UIVIew''s viewDidLoad`.

self.resultSearchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.searchBar.delegate = self controller.dimsBackgroundDuringPresentation = false controller.searchBar.sizeToFit() controller.hidesNavigationBarDuringPresentation = false //prevent search bar from moving controller.searchBar.placeholder = "Search for song" self.myTableView.tableHeaderView = controller.searchBar return controller })()

Justo después de que termine este cierre, aparece esta advertencia en la consola:

Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x154d39700>)

No entiendo lo que estoy haciendo mal. Esta pregunta similar no es realmente mi situación (al menos no lo creo). Que esta pasando?


Crear un controlador de búsqueda en viewDidLoad() y establecer su barra de búsqueda como la vista de título del elemento de navegación no crea una referencia fuerte al controlador de búsqueda, por lo que se desasigna.

Entonces, en lugar de hacer esto:

override func viewDidLoad() { super.viewDidLoad() // Create search controller let searchController = UISearchController(searchResultsController: nil) // Add search bar to navigation bar navigationItem.titleView = searchController.searchBar // Size search bar searchController.searchBar.sizeToFit() }

Usted debe hacer esto:

var searchController: UISearchController! override func viewDidLoad() { super.viewDidLoad() // Create search controller searchController = UISearchController(searchResultsController: nil) // Add search bar to navigation bar navigationItem.titleView = searchController.searchBar // Size search bar searchController.searchBar.sizeToFit() }


El mío funciona así

func initSearchControl(){ searchController = UISearchController(searchResultsController: nil) if #available(iOS 9.0, *) { searchController.loadViewIfNeeded() } else { let _ = self.searchController.view } searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false definesPresentationContext = true tableView.tableHeaderView = searchController.searchBar searchController.searchBar.sizeToFit() }

searchController.loadViewIfNeeded () resuelve el problema, pero debe llamarlo después de inicializar searchController


En Swift2 recibí el mismo mensaje de error debido a un error obvio:

let alertController = UIAlertController(title: "Oops", message:"bla.", preferredStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alertController, animated: true, completion: nil)

Debido a un estúpido error de copia de mí mismo, no había incluido la línea self.presentViewController. Esto causó el mismo error.


En la versión Swift 2.2 que funcionó para mí

deinit { self.searchController?.view.removeFromSuperview() }

¡Creo que es útil!


Hackeando algunas soluciones conseguí que la mía funcionara agregando líneas para verDidLoad antes de configurar completamente el UISearchController:

override func viewDidLoad() { super.viewDidLoad() self.navigationItem.rightBarButtonItem = self.editButtonItem() if #available(iOS 9.0, *) { self.resultSearchController.loadViewIfNeeded()// iOS 9 } else { // Fallback on earlier versions let _ = self.resultSearchController.view // iOS 8 } self.resultSearchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.dimsBackgroundDuringPresentation = false controller.searchBar.sizeToFit() self.tableView.tableHeaderView = controller.searchBar return controller })() self.tableView.reloadData() }


La vista de UISearchController debe eliminarse de su supervista antes de desasignar. (supongo que es un error)

C objetivo...

-(void)dealloc { [searchController.view removeFromSuperview]; // It works! }

Swift 3 ...

deinit { self.searchController.view.removeFromSuperview() }

Luché con este problema durante un par de semanas. ^^


Llego un poco tarde a la fiesta, pero esta es mi solución:

var resultSearchController: UISearchController! override func viewDidLoad() { super.viewDidLoad() self.resultSearchController = ({ let searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false searchController.searchBar.sizeToFit() return searchController })() self.tableView.tableHeaderView = self.resultSearchController.searchBar self.tableView.reloadData() }

Espero que te funcione.


No es un error. Parece que debe evitar crear ViewControllers sin presentarlos. Entonces, después de SomeViewController() o let variable: SomeViewController , debe llamar a algo así como self.presentViewController(yourViewController ...etc) . Si no hace eso, recibirá esta advertencia cuando este controlador de vista sea desasignado.


Parece que la vista tiene una carga lenta, si asignó el controlador y nunca lo muestra, la vista no se carga. En este caso, si el controlador se desasigna, recibirá esta advertencia. puede mostrarlo una vez, o llamarlo método loadViewIfNeed (), o usar ''let _ = controller.view'' para forzar la carga de la vista para evitar esta advertencia.


Resuelto! Fue una solución simple. Cambié este código

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController = UISearchController()

a esto:

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController: UISearchController!

Esto soluciona el problema.


Usé la respuesta de Derek, pero tuve que cambiarla ligeramente. La respuesta que se proporcionó falló porque la llamada a loadViewIfNeeded () ocurrió antes de que se definiera el resultSearchController. (Mi declaración fue

var resultSearchController: UISearchController!

) Entonces lo moví después y funcionó.

Si omití la llamada por completo, el error se mantuvo, así que estoy seguro de que es una parte esencial de la respuesta. No pude probarlo en iOS 8.


class SampleClass: UITableViewController, UISearchBarDelegate { private let searchController = UISearchController(searchResultsController: nil) override func viewDidLoad() { super.viewDidLoad() searchController.loadViewIfNeeded() // Add this line before accessing searchController } }