Qual é a diferença entre -[UIViewController viewWillAppear:]
e -[UIViewController viewDidAppear:]
?
Qual é a diferença entre -[UIViewController viewWillAppear:]
e -[UIViewController viewDidAppear:]
?
Respostas:
Em geral, é isso que eu faço:
1) ViewDidLoad - Sempre que adiciono controles a uma exibição que deve aparecer junto com a exibição, eu o coloco no método ViewDidLoad. Basicamente, esse método é chamado sempre que a exibição foi carregada na memória. Por exemplo, se minha visualização for um formulário com três marcadores, eu os adicionaria aqui; a visão nunca existirá sem essas formas.
2) ViewWillAppear : Eu uso o ViewWillAppear normalmente apenas para atualizar os dados no formulário. Portanto, para o exemplo acima, eu usaria isso para realmente carregar os dados do meu domínio no formulário. A criação de UIViews é bastante cara e você deve evitar o máximo possível fazer isso no método ViewWillAppear, porque quando isso é chamado, significa que o iPhone já está pronto para mostrar o UIView ao usuário e qualquer coisa pesada que você fizer aqui afetará o desempenho de maneira muito visível (como atrasos nas animações etc.).
3) ViewDidAppear : Finalmente, eu uso o ViewDidAppear para iniciar novos threads para coisas que levariam muito tempo para serem executadas, como, por exemplo, fazer uma chamada de serviço da web para obter dados extras para o formulário acima. já existe e está sendo exibido ao usuário, você pode mostrar uma boa mensagem "Aguardando" para o usuário enquanto obtém os dados.
viewWillAppear
? Você quer dizer fazer o download pela rede? Mas você também sugere o download de material viewDidAppear
?
ViewDidAppear
que você vai facilmente fazer confundir usuário sobre UI :)
viewDidLoad === >>> Coloque seu código de inicialização aqui. Não coloque dados dinâmicos que possam mudar durante o ciclo de vida da exibição. Portanto, se você está obtendo dados dos dados principais, não deseja fazê-lo aqui, se isso puder mudar durante a vida útil da exibição. Por exemplo: digamos que você tenha um controlador de tabulação. Você alterna da tab1 para a tab2 e altera algo no modelo da tab2. Se você voltar à tab1 e o código do seu modelo tiver sido feito em viewDidLoad, isso não será atualizado (supondo que você não esteja usando o KVO ou NSFetchedResultsController, etc.).
viewWillAppear === >>> Isso é chamado toda vez que a exibição está prestes a aparecer, independentemente de a exibição já estar na memória. Coloque seu código dinâmico aqui, como a lógica do modelo.
viewDidAppear === >>> Coloque aqui operações caras que você só quer fazer se tiver certeza de que a exibição está na tela, como chamadas de rede.
Aviso: se o aplicativo estiver em segundo plano e retornar ao primeiro plano, você precisará lidar com isso usando o NSNotificationCenter. Eu escrevi o código para isso nos comentários abaixo. Você pode pensar que o viewWillAppear / viewDidAppear será acionado. Coloque um ponto de interrupção lá e teste-o. Não dispara. Portanto, se algo mudou para o seu aplicativo enquanto estava em segundo plano, você precisará atualizá-lo usando as notificações.
O viewWillAppear
método é chamado antes de carregar a visualização real.
O viewDidAppear
método é chamado quando a exibição já está carregada e você deseja mostrar algo.
viewWillAppear:
■ Chamado antes que a visualização seja adicionada à hierarquia de visualizações da janela
■ Chamado antes de [vc.view layoutSubviews] (se necessário)
viewDidAppear :
■ Chamado após a visualização ser adicionada à hierarquia da visualização
■ Chamado após [vc.view layoutSubviews] (se necessário)
Algumas observações:
O viewDidLoad
método é chamado quando a exibição é instanciada pela primeira vez. IBOutlet
as referências são conectadas no momento em que isso foi chamado, mas não antes. O ponto frame
de vista pode não ser estabelecido no momento em que isso foi chamado. Este é um ótimo local para adicionar / configurar subvisões e suas restrições associadas. Mas se você estiver fazendo uma configuração manual de frame
valores com base nas dimensões da vista principal, a configuração desses quadros deve ser adiada até viewWillAppear
ou viewDidLayoutSubviews
.
O viewWillAppear
método é chamado quando a apresentação da exibição na hierarquia da exibição está prestes a começar. Notavelmente, isso é chamado no início da animação (se houver) da apresentação da exibição. Seu companheiro, viewWillDisappear
obviamente , é chamado quando a transição para longe dessa visão começa.
O viewDidAppear
método é chamado quando a apresentação da exibição é concluída, principalmente quando toda e qualquer animação associada termina. Seu companheiro, viewDidDisappear
obviamente , é chamado quando a transição para longe dessa visão é feita.
Duas advertências importantes:
viewDidLoad
é chamado uma vez e apenas uma vez, quando a exibição é instanciada pela primeira vez. Por outro lado, viewWillAppear
e viewDidAppear
será chamado não apenas quando a exibição for apresentada pela primeira vez, mas a cada vez subsequente, a mesma exibição em questão será reapresentada. Por exemplo, quando você apresentar uma exibição pela primeira vez, todos esses três métodos serão chamados. Se a vista em questão, posteriormente, apresenta outro ponto de vista que é posteriormente demitido, o viewWillAppear
e viewDidAppear
geralmente será chamado novamente quando a vista em questão é adicionado e animado de volta para a hierarquia de vista, mas viewDidLoad
não vai. viewDidLoad
é chamado somente quando essa instância específica é criada pela primeira vez.
Portanto, se você quiser fazer algo toda vez que uma exibição reaparecer (por exemplo, você a dispensa ou volta a exibir), faça-a em viewWillAppear
ou viewDidAppear
. Se você deseja que isso aconteça somente quando a visualização for instanciada pela primeira vez, faça isso viewDidLoad
.
A chamada de viewWillAppear
não garante que a transição para essa exibição seja concluída. Notavelmente, se você estiver usando uma transição interativa que é direcionada pela entrada do usuário em tempo real, mas essa transição interativa pode ser cancelada. Ou seja, apenas porque viewWillAppear
é chamado, não significa que viewDidAppear
será chamado. Geralmente é, mas se o gesto interativo for cancelado, não será (porque a transição nunca terminou).
Na WWDC 2013, no contexto de transições interativas, um apresentador brincou dizendo que deveria renomear viewWillAppear
para " viewMightAppear
, ou viewWillProbablyAppear
, ou iReallyWishThisViewWouldAppear
".
Um exemplo de um gesto interativo embutido é quando você usa um UINavigationController
e você "desliza da borda esquerda" para iniciar um pop na exibição. O viewWillAppear
será chamado para a vista à qual estão surgindo, mas se você cancelar que "swipe da borda esquerda" para voltar para o ponto de vista do qual você iniciou este gesto pop, o pop é cancelada e o viewDidAppear
para a vista você começou a voltar para nunca será chamado.
O efeito líquido disso é que você deve tomar cuidado para não escrever um código que pressupõe que todas as chamadas para viewWillAppear
serão seguidas eventualmente por uma chamada para viewDidAppear
. Se a transição for cancelada, não será esse o caso.
1) ViewWillAppear : a exibição carregada na memória, chamada uma vez no controlador de exibição e tinha seu quadro, mas ainda não apareceu para o usuário
2) ViewDidAppear : o controlador foi adicionado à hierarquia da visualização, para que você pudesse apresentar ao próximo controlador, também, a visualização fez o layout das subvisões
O primeiro acontece antes que a visualização apareça e o segundo acontece depois.
Resumindo:
-viewWillAppear -> atualizar dados (recarregar dados de uma visualização de tabela)
-viewDidAppear -> operações caras (chamada da API com um bom progresso!)
Caso de uso , ou seja, quando devo usar qual?
viewDidLoad
- quando etiquetas, botões (ou seja, controles / sub-visualizações) estão conectados ao arquivo de interface do View e se você deseja carregar todos esses itens ao mesmo tempo que o ViewController, e se você deseja carregá-lo na memória uma vez e feito com isso
viewWillAppear
- digamos, você deseja alterar a cor de fundo da exibição sempre que o controlador de exibição aparecer na tela. Ou, de forma mais realista, se você quiser a cor de fundo do DarkMode no período noturno do dia e a cor clara da exibição de plano de fundo durante o dia, vá para este código emviewWillAppear
Outro bom caso de uso aqui https://stackoverflow.com/a/39395865/5438240
Observe também que, se você estiver usando uma pilha de Navegação ( UINavigationController
), o viewController que está prestes a ser exibido terá a viewWillDisappear()
chamada e o ViewController que será o próximo no topo da pilha terá viewWillAppear()
chamado