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
}
}