Хотя viewWillAppear()
и viewDidDisappear()
вызываются, когда нажата кнопка «Назад», они также вызываются в другое время. Смотрите конец ответа для более подробной информации.
Использование UIViewController.parent
Обнаружение кнопки возврата лучше сделать, когда VC удален из родительского элемента (NavigationController) с помощью willMoveToParentViewController(_:)
ИЛИdidMoveToParentViewController()
Если parent равен nil, контроллер представления извлекается из стека навигации и удаляется. Если parent не равен nil, он добавляется в стек и представляется.
// 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
}
}
Выгрузить willMove
для didMove
и проверки self.parent сделать работу после того, как контроллер зрения уволен.
Остановка увольнения
Обратите внимание, что проверка родителя не позволяет вам «приостановить» переход, если вам нужно выполнить какое-то асинхронное сохранение. Для этого вы можете реализовать следующее. Единственный недостаток - вы теряете красивую анимированную кнопку возврата в стиле iOS. Также будьте осторожны с интерактивным жестом. Используйте следующие для обработки этого случая.
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
}
}
}
Больше на вид будет / действительно появится
Если viewWillAppear
viewDidDisappear
проблема не возникла, давайте рассмотрим пример. Скажем, у вас есть три контроллера вида:
- ListVC: табличное представление вещей
- DetailVC: подробности о вещи
- Настройки ВК: некоторые варианты вещи
Давайте следовать звонки на , detailVC
как вы идете от listVC
к settingsVC
и обратноlistVC
Список> Детализация (push detailVC) Detail.viewDidAppear
<- появляется
Деталь> Настройки (push settingsVC) Detail.viewDidDisappear
<- исчезает
И как мы вернемся ...
Настройки> Подробно (всплывающие настройки ВК) <- Detail.viewDidAppear
Появляются
подробности> Список (всплывающие подробности ВК) Detail.viewDidDisappear
<- исчезают
Обратите внимание, что viewDidDisappear
вызывается несколько раз, не только при движении назад, но и при движении вперед. Для быстрой операции, которая может быть желательной, но для более сложной операции, такой как сетевой вызов, для сохранения, это может не сработать.