ViewDidAppear маршрутизации iOS для контроллеров дочерних представлений?

Я добавляю дочерний контроллер представления к родительскому контроллеру представления, и все работает, как ожидалось, за исключением того, что у этого контроллера дочернего представления не запускаются обычные обратные вызовы. например, такие вещи, как viewWillAppear (animated), никогда не вызываются. Я изучил это и подумал, что это может быть потому, что я не вызывал willMoveToParentViewController и didMoveToParentViewController на контроллере дочернего представления до и после добавления его к родительскому, соответственно. К сожалению, исправление не имело никакого значения. Кто-нибудь знает, как я могу это подключить, чтобы при добавлении addChildViewController и removeChildViewController запускались обычные обратные вызовы? После добавления childViewController я также добавляю его представление в качестве подпредставления к представлению родительского контроллера представления. Ни в одной точке (addChildViewController и addSubview) не вызываются методы viewWillAppear (анимированные) и т. Д. Контроллера дочернего представления ...

Ник


person pachun    schedule 24.12.2013    source источник


Ответы (6)


viewWillAppear, viewDIdAppear вызывается автоматически при добавлении представления ViewControler в иерархию представлений.

viewWillDisappear, viewDidDisappear вызывается автоматически при удалении представления ViewControler из иерархии представлений.

Возможно, эти методы не вызываются, потому что вы добавляете представление субконтроллера перед отображением контроллера основного представления и, следовательно, ваше основное представление не находится в поле зрения самого hiererchy?

Когда ваш главный контроллер представления появляется или исчезает, вы должны вызывать эти методы для дочерних элементов в соответствующих методах.

person VChemezov    schedule 25.12.2013

Не уверен, что это применимо к вашей ситуации, но попробуйте поэкспериментировать с ручной отправкой методов обратного вызова внешнего вида своим детям.

Из документации из контейнера представления Apple:

Однако иногда поведение по умолчанию может отправлять эти события в порядке, не имеющем смысла для вашего контейнера. Например, если несколько дочерних элементов одновременно изменяют свое состояние просмотра, вы можете объединить изменения, чтобы все обратные вызовы внешнего вида выполнялись одновременно в более логичном порядке. Для этого вы модифицируете свой контейнерный класс, чтобы взять на себя ответственность за обратные вызовы появления или вращения.

Он рекомендует вручную пересылать обратные вызовы внешнего вида своим детям, если вы хотите более детальный контроль:

// From the container view controller
- (BOOL) shouldAutomaticallyForwardAppearanceMethods
{
    return NO;
}

-(void) viewWillAppear:(BOOL)animated
{
    [self.child beginAppearanceTransition: YES animated: animated];
}

-(void) viewDidAppear:(BOOL)animated
{
    [self.child endAppearanceTransition];
}

-(void) viewWillDisappear:(BOOL)animated
{
    [self.child beginAppearanceTransition: NO animated: animated];
}

-(void) viewDidDisappear:(BOOL)animated
{
    [self.child endAppearanceTransition];
}
person chourobin    schedule 04.03.2015

Попробуй это:

childController.willMoveToParentViewController(self)
childController.beginAppearanceTransition(true, animated: true)

после добавления в ваш контроллер просмотра

person patuan81    schedule 03.09.2015
comment
Обязательно вызовите childController.endAppearanceTransition() после завершения перехода анимации, иначе viewDidAppear не будет вызван! - person dvdblk; 31.07.2018

Просто попробовал сделать следующее в viewDidLoad в родительском контроллере просмотра, и, похоже, он работает

ChildExperimentViewController *child = [[ChildExperimentViewController alloc]init];
[self addChildViewController:child];
[self.view addSubview:child.view];
[child didMoveToParentViewController:self];
person djshiow    schedule 24.12.2013

Chourobin ответ в Swift:

override var shouldAutomaticallyForwardAppearanceMethods: Bool {
    return false
}

override func viewWillAppear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].beginAppearanceTransition(true, animated: animated)
}

override func viewDidAppear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].endAppearanceTransition()
}

override func viewWillDisappear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].beginAppearanceTransition(false, animated: animated)
}

override func viewDidDisappear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].endAppearanceTransition()
}

P.S. Поскольку я не сохраняю ссылку на дочерний VC как свойство или переменную. Я предпочитаю получать к нему доступ, используя текущий выбранный индекс сегмента. SegmentView является сторонней организацией UISegmentControl.

person Hemang    schedule 11.09.2017

Вы можете вручную вызвать дочерний контроллер представления viewWillAppear в parectViewController, такой код

-(void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [selectedViewController viewWillAppear:animated];
}

если вы добавили navigationController как childViewController, вы можете добавить такой код в делегат navigationController

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{
    [viewController viewWillAppear:animated];
}

если вы добавили tabBarController как childViewController, вы можете добавить такой код в делегат tabBarController и суперпредставление

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [self.tabBarController.selectedViewController viewWillAppear:animated]; 
}

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { 
    [viewController viewWillAppear:NO]; 
}

Я не знаю, может ли это решить вашу проблему, надеюсь, смогу вам помочь.

person Dracuuula    schedule 24.12.2013
comment
Мы никогда не должны вызывать viewWillAppear или другие методы вручную. Пожалуйста, обратитесь к developer.apple.com/library/ios/documentation/UIKit/Reference/: - person vivek; 25.09.2015