UIViewController viewDidLoad vs. viewWillAppear: Qual é a divisão apropriada do trabalho?


164

Sempre fui um pouco claro sobre o tipo de tarefas que devem ser atribuídas a viewDidLoadvs viewWillAppear.: em uma UIViewControllersubclasse.

por exemplo, estou fazendo um aplicativo no qual uma UIViewControllersubclasse atinge um servidor, obtendo dados, alimentando-os com uma visualização e exibindo essa visualização. Quais são os prós e contras de se fazer isso em viewDidLoadvs. viewWillAppear?

Respostas:


251

viewDidLoad é o que você precisa fazer uma vez. O viewWillAppear é chamado toda vez que a exibição é exibida. Você deve fazer coisas que precisa fazer apenas uma vez no viewDidLoad - como definir os textos do UILabel. No entanto, convém modificar uma parte específica da visualização toda vez que o usuário a visualizar, por exemplo, o aplicativo iPod rolar a letra de volta ao topo toda vez que você acessar a visualização "Em execução".

No entanto, quando você está carregando coisas de um servidor, também precisa pensar em latência. Se você agrupar toda a sua comunicação de rede em viewDidLoad ou viewWillAppear, elas serão executadas antes que o usuário veja a visualização - possivelmente resultando em um curto congelamento do seu aplicativo. Pode ser uma boa ideia primeiro mostrar ao usuário uma visão não preenchida com algum tipo de indicador de atividade. Quando você terminar sua rede, o que pode levar um ou dois segundos (ou até falhar - quem sabe?), Você pode preencher a exibição com seus dados. Bons exemplos de como isso pode ser feito podem ser vistos em vários clientes do twitter. Por exemplo, quando você visualiza a página de detalhes do autor no Twitterrific, a exibição diz apenas "Carregando ..." até que as consultas de rede sejam concluídas.


Portanto, sobre o viewWillAppear potencialmente sendo chamado repetidamente. Esse método seria acionado se, por exemplo, a visualização dos controladores de exibição se tornasse visível depois de ocultada (quero dizer, ocluída aqui, não o método oculto no UIView). Em que cenário o viewWillAppear seria chamado sem ser precedido por uma chamada para viewDidLoad?
21468 dugla

7
viewDidLoad ONLY é chamado quando a exibição é construída - por exemplo, após uma chamada initFromNibNamed do controlador de exibição quando a exibição é acessada. O viewWillAppear é chamado sempre que seu controlador de exibição não estava em exibição, mas é exibido - portanto, quando seu controlador de exibição é pressionado, o viewWillAppear é chamado. Se você enviar outra subvisão a partir daí e o usuário retornar, o viewWillAppear será chamado novamente.
Kendall Helmstetter Gelner

Obrigado Kendall. Sim, alguns NSLogs estrategicamente posicionados me classificaram. viewWillAppear / viewWillDissappear dispara no push / pops do controlador de exibição.
dugla 16/10/09

3
Observe que o viewDidLoad TAMBÉM será chamado se o modo de exibição estiver oculto e depois descarregado por motivos relacionados à memória, e reaparecerá. Com o que você pode contar: viewDidLoad será chamado PELO MENOS UMA VEZ quando a exibição for criada pela primeira vez e POSSÍVEL MAIS vezes quando a exibição reaparecer após ser ocultada. O viewWillAppear SEMPRE será chamado quando a exibição estiver prestes a aparecer na tela.
DanM 17/01

2
Alguém pode comentar mais sobre essas duas questões relacionadas: (1) Às vezes, nem sempre, os valores de quadros dos controles (ou seja, origem e tamanho) são zero em viewDidLoad e, às vezes, não --Por que? (2) No modelo da Apple para o detailView (iPad) de um splitViewController, existe um método configureView - o que deve ser incluído em relação a viewDidLoad e ViewWillAppear?
26413 Jeff Jeff

12

Inicialmente usado apenas ViewDidLoad com tableView. Nos testes com perda de Wifi, ao definir o dispositivo no modo avião, percebemos que a tabela não era atualizada com o retorno de Wifi. De fato, parece não haver maneira de atualizar o tableView no dispositivo, mesmo pressionando o botão home com o modo de plano de fundo definido como YES no -Info.plist.

Minha solução:

-(void) viewWillAppear: (BOOL) animated { [self.tableView reloadData];}

10

É importante observar que o uso do viewDidLoad para posicionamento é um pouco arriscado e deve ser evitado, pois os limites não estão definidos. isso pode causar resultados inesperados (tive vários problemas ...)

Este post descreve muito bem os diferentes métodos e o que acontece em cada um deles.

atualmente para inicialização e posicionamento únicos, estou pensando em usar o viewDidAppear com um sinalizador, se alguém tiver alguma outra recomendação, entre em contato.


concordo com esta: "... deve ser evitado uma vez que os limites não estão definidas ..."
danisupr4

4

Depende, você precisa que os dados sejam carregados toda vez que você abre a exibição? ou apenas uma vez ?

insira a descrição da imagem aqui

  • Vermelho: eles não precisam mudar sempre. Uma vez carregados, permanecem como estavam.
  • Roxo: eles precisam mudar com o tempo ou após o carregamento de cada vez. Você não deseja ver os mesmos três usuários sugeridos a seguir, ele precisa ser recarregado toda vez que você voltar à tela. As fotos deles podem ser atualizadas ... você não quer ver uma foto de 5 anos atrás ...

viewDidLoad:Qualquer que seja o processamento que você tenha, precisa ser feito uma vez.
viewWilLAppear:Qualquer processamento que precise ser alterado sempre que a página for carregada.

Rótulos, ícones, títulos de botão ou a maioria dos dataInputedByDeveloper geralmente não são alterados. Nomes, fotos, links, status dos botões, listas (matrizes de entrada para seus tableViews ou collectionView) ou a maioria dos dadosInputedByUser geralmente são alterados.


O roxo seria chamado no viewDidAppear não no viewWillAppear
Alex Kornhauser

@AlexKornhauser, como assim, seria chamado? Estou dizendo que viewWillAppearvocê pode consultar e verificar os últimos tweets. viewDidAppearé tarde demais para isso #
405
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.