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?
ViewDidAppearque 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 viewWillAppearmétodo é chamado antes de carregar a visualização real.
O viewDidAppearmé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 viewDidLoadmétodo é chamado quando a exibição é instanciada pela primeira vez. IBOutletas referências são conectadas no momento em que isso foi chamado, mas não antes. O ponto framede 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 framevalores com base nas dimensões da vista principal, a configuração desses quadros deve ser adiada até viewWillAppearou viewDidLayoutSubviews.
O viewWillAppearmé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, viewWillDisappearobviamente , é chamado quando a transição para longe dessa visão começa.
O viewDidAppearmétodo é chamado quando a apresentação da exibição é concluída, principalmente quando toda e qualquer animação associada termina. Seu companheiro, viewDidDisappearobviamente , é 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, viewWillAppeare viewDidAppearserá 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 viewWillAppeare viewDidAppeargeralmente será chamado novamente quando a vista em questão é adicionado e animado de volta para a hierarquia de vista, mas viewDidLoadnã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 viewWillAppearou 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 viewWillAppearnã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 viewDidAppearserá 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 viewWillAppearpara " viewMightAppear, ou viewWillProbablyAppear, ou iReallyWishThisViewWouldAppear".
Um exemplo de um gesto interativo embutido é quando você usa um UINavigationControllere você "desliza da borda esquerda" para iniciar um pop na exibição. O viewWillAppearserá 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 viewDidAppearpara 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 viewWillAppearserã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