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.Respostas:
Tive um problema semelhante recentemente. Tive que removê-lo manualmente
UITransitionView
da janela para corrigir o problema e, em seguida, chamar dispense no controlador de visualização root anterior para garantir que fosse desalocado.A correção não é realmente muito boa, mas a menos que você tenha encontrado uma maneira melhor desde a postagem da pergunta, é a única coisa que descobri que funciona!
viewController
é apenas onewController
da sua pergunta original.Espero que isso ajude você a resolver seu problema também, é um pé no saco!
(Veja o histórico de edição para outras versões do Swift)
Para uma implementação mais agradável como uma extensão em
UIWindow
permitir que uma transição opcional seja passada.Uso:
Ou
fonte
UITransitionView
em seu aplicativo, pois é escolhida como parte dos símbolos do aplicativo que eu acho que a App Store usa para verificar.Enfrentei esse problema e isso me incomodou um dia inteiro. Eu tentei a solução obj-c do @Rich e descobri que quando eu quiser apresentar outro viewController depois disso, serei bloqueado com um UITransitionView em branco.
Finalmente, descobri dessa forma e funcionou para mim.
Tudo bem, agora tudo o que você precisa fazer é chamar
[self setRootViewController:newViewController];
quando quiser mudar o controlador de visualização raiz.fonte
dismissViewControllerAnimated:
aparência talvez seja um pouco melhor do que nenhuma animação. NoUITransitionView
entanto, evita os fantasmas na hierarquia de visualizações.Eu tento uma coisa simples que funciona para mim no iOs 9.3: apenas remover a visão do antigo viewController de sua hierarquia durante a
dismissViewControllerAnimated
conclusão.Vamos trabalhar nas visualizações X, Y e Z, conforme explicado por benzado :
Que dão:
No meu caso, X e Y estão bem desalocados e a visão deles não está mais na hierarquia!
fonte
Teve um problema semelhante. No meu caso, eu tinha uma hierarquia viewController e um dos controladores de visualização filho tinha um controlador de visualização apresentado. Quando mudei o controlador de visualização do Windows root, por algum motivo, o controlador de visualização apresentado ainda estava na memória. Portanto, a solução foi dispensar todos os controladores de visualização antes de alterar o controlador de visualização raiz do Windows.
fonte
Eu cheguei a este problema ao usar este código:
Desativar este código corrigiu o problema. Consegui fazer isso funcionar habilitando essa animação de transição apenas quando a barra de filtros que fica animada é inicializada.
Não é realmente a resposta que você está procurando, mas pode levá-lo ao ponto certo para encontrar sua solução.
fonte