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
})()
Inmediatamente después de que finalice este cierre, esta advertencia aparece 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?
ios
swift
uisearchcontroller
MortalMan
fuente
fuente
viewDidLoad()
. Recomiende a) incluir la lista completa de fuentes de VC yb) asegurarse de que el error realmente esté ocurriendo donde y cuando usted cree que está.})()
y después})()
. El error se produce después de que finaliza el cierre. Tengo unUIViewController
, no untableViewController
.Respuestas:
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! }
Rápido 3 ...
deinit { self.searchController.view.removeFromSuperview() }
Luché con este problema durante un par de semanas. ^^
fuente
UISearchControler
asignación en-viewDidLoad
. Definitivamente es un error: siUISearchController
se desasigna antes de que se cargue su vista, aparecerá esta advertencia. Si toco el campo de búsqueda (cargando así la vista), no aparece. Entonces, en midealloc
, llamo[self.searchController loadViewIfNeeded]
(nuevo en iOS 9),if #available(iOS 9.0, *) { self.searchController?.loadViewIfNeeded() }
[self.searchController loadViewIfNeeded];
(Obj-C) es la respuesta que resolvió el problema en mi código.¡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.
fuente
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() } }
fuente
if let
puesto.removeFromSuperView()
que no hará nada sisuperview == nil
class SampleClass: UITableViewController, UISearchBarDelegate { private let searchController = UISearchController(searchResultsController: nil) override func viewDidLoad() { super.viewDidLoad() searchController.loadViewIfNeeded() // Add this line before accessing searchController } }
fuente
Hackeando algunas soluciones, logré que la mía funcionara agregando líneas a viewDidLoad 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() }
fuente
self.searchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.dimsBackgroundDuringPresentation = false controller.searchBar.delegate = self definesPresentationContext = true controller.searchBar.sizeToFit() return controller })()
entoncesself.searchController.loadViewIfNeeded()
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 error de copia estúpido de mí mismo, no había incluido la línea self.presentViewController. Esto provocó el mismo error.
fuente
En la versión Swift 2.2 que funcionó para mí
deinit { self.searchController?.view.removeFromSuperview() }
¡Creo que es útil!
fuente
No es un error. Parece que debe evitar crear ViewControllers sin presentarlos. Así que después
SomeViewController()
olet variable: SomeViewController
tienes que llamar a algo como estoself.presentViewController(yourViewController ...etc)
. Si no lo hace, recibirá esta advertencia cuando se desubique este controlador de vista.fuente
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 el searchController
fuente
La creación de un controlador de búsqueda
viewDidLoad()
y la configuración de su barra de búsqueda como vista de título del elemento de navegación no crea una referencia sólida 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() }
fuente
Usé la respuesta de Derek, pero tuve que cambiarla ligeramente. La respuesta que se proporcionó se bloqueó porque la llamada a loadViewIfNeeded () ocurrió antes de que se definiera el resultSearchController. (Mi declaración fue
var resultSearchController: UISearchController!
). Así que 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.
fuente
Parece que la vista se carga de forma diferida, si asignó el controlador y nunca lo muestra, la vista no se carga. En este caso, si se cancela la asignación del controlador, recibirá esta advertencia. podría mostrarlo una vez, o llamar a su método loadViewIfNeed (), o usar 'let _ = controller.view' para forzar la carga de la vista para evitar esta advertencia.
fuente
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.
fuente