ti-enxame.com

Como o View Controller Conttainment funciona no iOS 5?

Na Sessão 102 da WWDC 2011, Apple introduziu View Controller Containment, que é a capacidade de criar contêineres personalizados de controladores de exibição, análogos a UITabBarController, UINavigationController e similares.

Eu assisti os exemplos várias vezes. Existem vários métodos associados a esse padrão, mas foi um pouco difícil descobrir exatamente. Vou postar aqui o que acho que está acontecendo e ver se a comunidade confirmará ou desconfirmará minhas suspeitas.

Cenário 1: Mudando de nenhum pai para um novo controlador de exibição pai

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

As duas primeiras linhas devem ocorrer na ordem indicada ou podem ser revertidas?

Cenário 2: Movendo-se de um controlador de exibição pai para nenhum controlador de exibição pai

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

Também é necessário chamar [vc didMoveToParentViewController:nil]? Os exemplos na sessão 102 não fizeram isso nesse cenário, mas não sei se isso foi uma omissão ou não.

Cenário 3: Movendo-se de um controlador de exibição pai para outro

Isso provavelmente ocorrerá da seguinte maneira, porque a lógica em cada controlador de exibição pai será encapsulada.

// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];

Perguntas

Minha principal pergunta é a seguinte: é assim que a retenção de controladores de exibição deve funcionar, em geral? As mecânicas dadas acima estão corretas?

É necessário chamar willMoveToParentViewController antes de chamar addChildViewController? Parece-me a ordem lógica, mas é estritamente necessário?

É necessário chamar didMoveToParentViewController:nil depois de chamar removeFromParentViewController?

107
Gregory Higley

Os documentos UIViewController são bastante claros sobre quando e quando não chamar os métodos willMove/didMove. Confira a documentação "Implementando um Container View Controller" .

Os documentos dizem que, se você não substituir addChildViewController, não precisará chamar o método willMoveToParentViewController:. No entanto, você precisa chamar o método didMoveToParentViewController: após a conclusão da transição. "Da mesma forma, é responsabilidade do controlador de exibição de contêiner chamar o método willMoveToParentViewController: antes de chamar o método removeFromParentViewController. O método removeFromParentViewController chama o método didMoveToParentViewController: da criança ver controlador ".

Além disso, há um exemplo elaborado aqui e código de amostra aqui .

Boa sorte

73
timthetoolman

Esta parte não está correta:

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

De acordo com os documentos:

Quando seu contêiner personalizado chama o método addChildViewController:, ele automaticamente chama o método willMoveToParentViewController: do controlador de exibição para ser adicionado como filho antes de adicioná-lo.

Portanto, você não precisa da chamada [vc willMoveToParentViewController:self]. Isso é feito automaticamente quando você chama [self addChildViewController:vc]. Aqui está o exemplo de código novamente:

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Para remover os controladores de exibição:

O método removeFromParentViewController chama automaticamente o método didMoveToParentViewController: do controlador de exibição filho depois que ele remove o filho.

Presumivelmente, esta ligação é [oldVC didMoveToParentViewController:nil].

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically
22
nevan king