DidMoveToParentViewController вызывается дважды

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


- (IBAction)myInfoAddAction:(id)sender {
    profileViewController = [[ProfileViewController alloc] init];
    [self addChildViewController: profileViewController];
    UIView *__view = profileViewController.view;
    [self.view addSubview: __view];
    [profileViewController didMoveToParentViewController: self];
}

- (IBAction)myInfoRemoveAction:(id)sender {
    [profileViewController willMoveToParentViewController: nil];
    [profileViewController.view removeFromSuperview];
    [profileViewController removeFromParentViewController];
}

Класс ProfileViewController расширяет UIViewController и переопределяет методы willMoveToParentViewController и didMoveToParentViewController


-( void)willMoveToParentViewController:(UIViewController *)parent
{
    [super willMoveToParentViewController: parent];
    NSLog(@"willMoveToParentViewController -> %@", self);
}

-( void) didMoveToParentViewController:(UIViewController *)parent
{
    [super didMoveToParentViewController: parent];
    NSLog(@"didMoveToParentViewController -> %@", self);
}

-( void)viewWillAppear:(BOOL)animated
{
    NSLog(@"viewWillAppear -> %@", self);
}

-( void)viewDidDisappear:(BOOL)animated
{
    NSLog(@"viewDidDisappear -> %@", self);
}

Когда я добавляю контроллер представления, я получил следующие журналы:


willMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>
viewWillAppear -> <ProfileViewController: 0x8c52ea0>
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>

Когда я удаляю контроллер представления:


willMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>
viewDidDisappear -> <ProfileViewController: 0x8c52ea0>
didMoveToParentViewController -> <ProfileViewController: 0x8c52ea0>

Я хотел бы знать, почему didMoveToParentViewController вызывается дважды?

Спасибо!

Ответ 1

У меня была такая же проблема. Кроме того, я обнаружил, что когда я добавил контроллер дочернего представления во время viewDidLoad, у меня было только одно сообщение. Я установил его, удалив вызов [super didMoveToParentViewController:]. Я думаю, что проблема связана с добавлением контроллеров дочерних элементов во время обратного вызова с помощью кнопки, но я не уверен, почему это должно вызывать проблему.

Ответ 2

Можно отфильтровать повторяющиеся системные вызовы didMoveToParentViewController, проверив текущий родительский контроллер представления. В этом случае мы можем использовать супервызов, как и должно быть.

- (void)didMoveToParentViewController:(UIViewController *)parent {
    [super didMoveToParentViewController:parent];

    if (parent == nil && self.parentViewController == nil) return;
    if (parent != nil && self.parentViewController == parent) return;

    // From here any code called once
}

Ответ 3

Вы должны вызвать суперфункцию 'viewWillAppear' и 'viewDidDisappear'