Ao investigar um vazamento de memória, descobri um problema relacionado à técnica de chamada setRootViewController:
dentro de um bloco de animação de transição:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Se o controlador de visão antigo (o que está sendo substituído) está apresentando outro controlador de visão, o código acima não remove a visão apresentada da hierarquia de visão.
Ou seja, esta sequência de operações ...
- X torna-se Controlador de Visualização Root
- X apresenta Y, de modo que a visão de Y esteja na tela
- Usando
transitionWithView:
para fazer de Z o novo controlador de visualização raiz
... parece OK para o usuário, mas a ferramenta Debug View Hierarchy revelará que a visão de Y ainda está lá atrás da visão de Z, dentro de a UITransitionView
. Ou seja, após as três etapas acima, a hierarquia de visualização é:
- UIWindow
- UITransitionView
- UIView (visualização de Y)
- UIView (visão de Z)
- UITransitionView
Suspeito que isso seja um problema porque, no momento da transição, a visualização de X não faz parte da hierarquia de visualizações.
Se eu enviar dismissViewControllerAnimated:NO
para X imediatamente antes transitionWithView:
, a hierarquia de visualização resultante será:
- UIWindow
- UIView (visualização de X)
- UIView (visão de Z)
Se eu enviar dismissViewControllerAnimated:
(SIM ou NÃO) para X, então faço a transição no completion:
bloco, então a hierarquia de visualização está correta. Infelizmente, isso interfere na animação. Se animar a dispensa, é uma perda de tempo; se não estiver animando, parece quebrado.
Estou tentando algumas outras abordagens (por exemplo, fazer uma nova classe de controlador de visualização de contêiner para servir como meu controlador de visualização raiz), mas não encontrei nada que funcione. Vou atualizar esta pergunta à medida que avançar.
O objetivo final é fazer a transição da visão apresentada para um novo controlador de visão raiz diretamente e sem deixar hierarquias de visão perdidas ao redor.
UIWindow
é a coisa certa a fazer, mas não tive tempo de experimentar muito.