viewWillAppear не вызывается после popToViewController
У меня небольшая проблема. Я работаю над простым приложением с контроллерами представлений в контроллере навигации, например: A->B->C (-> являются модальными переходами). Представление A является корневым контроллером, и мне нужно вернуться к A из C. Если Я вызываю метод popToViewController из B, A запускаю viewWillAppear; если я вызываю popToViewController из C (в A), viewWillAppear для A не вызывается. Как я могу решить это? (Работает на Xcode7 и iOS 9)
ViewController A
#import "ViewControllerA.h"
#import "ViewControllerB.h"
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupSceneA];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"goToB"]) {
ViewControllerB *b = [segue destinationViewController];
}
}
ViewController B
#import "ViewControllerB.h"
#import "ViewControllerC.h"
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupSceneB];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"goToC"]) {
ViewControllerC *c = [segue destinationViewController];
}
}
- (IBAction)backToAButton:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
}
ViewController C
#import "ViewControllerC.h";
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupSceneC];
}
- (IBAction)backToBButton:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)backToAButton:(id)sender {
[[self parentViewController] dismissViewControllerAnimated:NO completion:nil];
}
2 ответа
Это должен быть ваш дизайн:
Контроллер A -> модальный переход к контроллеру Nav (контроллер B является корневым контроллером) -> передача перехода к контроллеру C.
Так что если вы хотите перейти с C на B, вы делаете поп.
Когда вы хотите перейти из B в A или из C в A, вы делаете отставку.
Если вы реализуете один из этих двух случаев, представленных ниже, вы обязательно получите viewWillAppear
и убедитесь, что вы написали это правильно с этим super
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Your code goes here
}
Случай 1 - Использование контроллера навигации
Если вы хотите перемещаться с одного ViewController на другой, вам нужно, чтобы все они были в одном стеке навигации. Это означает, что каждый раз, когда вы хотите открыть новый View Controller, вам нужно сделать что-то вроде этого:
[self.navigationController pushViewController:nextVC animated:YES];
вместо этого
[self presentViewController:nextVC animated:YES completion:nil];
И после этого, если у вас уже есть все VC в этом же навигационном контроллере, вы можете использовать этот код, чтобы вернуться на один шаг назад (например, от B к A, от C к B)
[self.navigationController popViewControllerAnimated:YES];
И вы можете использовать этот код, чтобы перейти к началу (например, от C до A)
[self.navigationController popToRootViewControllerAnimated:YES];
Случай 2 - Обычный цикл (похоже на то, что вам нужно)
Это простой случай, но вы должны быть осторожнее с вашим кодом. Вы можете просто получить родительский родитель, чтобы оставить текущий View Controller
[[[selfingingViewController] presentingViewController] dismissViewControllerAnimated:NO завершение:nil];
Примечание: Вы не можете использовать функции контроллера навигации с функциями модального представления. Толчок с поп, настоящее с увольнением
ОБНОВЛЕНИЕ 1
Модальные сегменты создают вложенное соединение (одна строка дерева). Если вы закрываете дочерний (текущий) VC, родительский VC отображается нормально. Если вы хотите перейти к родителю родителя, просто отклоните родителя, и он отклонит все его дочерние VC. Я не знаю, почему popViewControllerAnimated отлично работает от B до A, но вам не разрешено делать это. Просто используйте dismiss, если вы используете модальные сегы. Никогда не используйте Pop. Поп для толчка. Сделайте это, и все должно работать нормально.
Для перехода из B в A измените свой код на:
[self dismissViewControllerAnimated:YES completion:nil];
Для возврата из C в A используйте этот код:
[[self parentViewController] dismissViewControllerAnimated:YES completion:nil];
ИЛИ ЖЕ
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
ОБНОВЛЕНИЕ 2
Я обнаружил, что для сегментов STORYBOARD нам нужно использовать этот код, чтобы вернуться
[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:NO completion:nil];
Этот код прекрасно переходит с C на A и viewWillAppear
называется НО viewWillAppear
вызывается как в А и В
У вас есть 3 трека на выбор (на самом деле у вас есть больше, например, использование делегатов и уведомлений, но это очень плохо)
- Придерживайтесь этой версии, но она не надежна.
- Продолжайте использовать раскадровку, но для использования кнопки backCtoA соединитесь с A из VC C, чтобы она всегда зацикливалась, но загружалась снова каждый раз. Плохо, но все еще хорошо.
- Наконец, правильное решение - перейти к контроллеру навигации (кстати, вы можете скрыть панель навигации, если хотите) и иметь стек VC, чтобы вы могли легко использовать popToViewController.