Mientras viewWillAppear()
y viewDidDisappear()
se llaman cuando se toca el botón Atrás, también se llaman en otros momentos. Vea el final de la respuesta para más información sobre eso.
Usando UIViewController.parent
La detección del botón Atrás se realiza mejor cuando el VC se elimina de su padre (el NavigationController) con la ayuda de willMoveToParentViewController(_:)
ORdidMoveToParentViewController()
Si padre es nulo, el controlador de vista se saca de la pila de navegación y se descarta. Si padre no es nulo, se agrega a la pila y se presenta.
// Objective-C
-(void)willMoveToParentViewController:(UIViewController *)parent {
[super willMoveToParentViewController:parent];
if (!parent){
// The back button was pressed or interactive gesture used
}
}
// Swift
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
// The back button was pressed or interactive gesture used
}
}
Intercambiar willMove
para didMove
y verificación self.parent para hacer el trabajo después del controlador de vista es despedido.
Deteniendo el despido
Tenga en cuenta que verificar el padre no le permite "pausar" la transición si necesita hacer algún tipo de guardado asíncrono. Para hacer eso, podría implementar lo siguiente. El único inconveniente aquí es que pierdes el elegante botón de retroceso animado / estilo iOS. También tenga cuidado aquí con el gesto de deslizamiento interactivo. Use lo siguiente para manejar este caso.
var backButton : UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
// Disable the swipe to make sure you get your chance to save
self.navigationController?.interactivePopGestureRecognizer.enabled = false
// Replace the default back button
self.navigationItem.setHidesBackButton(true, animated: false)
self.backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
self.navigationItem.leftBarButtonItem = backButton
}
// Then handle the button selection
func goBack() {
// Here we just remove the back button, you could also disabled it or better yet show an activityIndicator
self.navigationItem.leftBarButtonItem = nil
someData.saveInBackground { (success, error) -> Void in
if success {
self.navigationController?.popViewControllerAnimated(true)
// Don't forget to re-enable the interactive gesture
self.navigationController?.interactivePopGestureRecognizer.enabled = true
}
else {
self.navigationItem.leftBarButtonItem = self.backButton
// Handle the error
}
}
}
Más sobre la vista aparecerá / apareció
Si no obtuvo el viewWillAppear
viewDidDisappear
problema, veamos un ejemplo. Digamos que tiene tres controladores de vista:
- ListVC: una vista de tabla de cosas
- DetailVC: detalles sobre una cosa
- SettingsVC: algunas opciones para algo
Vamos a seguir las llamadas en la detailVC
medida que avanza de la listVC
a settingsVC
y de nuevo alistVC
List> Detail (push detailVC) Detail.viewDidAppear
<- aparece
Detail> Settings (push settingsVC) Detail.viewDidDisappear
<- desaparecer
Y a medida que retrocedemos ...
Configuración> Detalle (pop settingsVC) Detail.viewDidAppear
<- aparece
Detalle> Lista (pop detailVC) Detail.viewDidDisappear
<- desaparece
Tenga en cuenta que viewDidDisappear
se llama varias veces, no solo al retroceder, sino también al avanzar. Para una operación rápida que puede desearse, pero para una operación más compleja como una llamada de red para guardar, puede que no.