viewDidLoad é o primeiro método que o UIKit chama após carregar a View do UIViewController na memória. De acordo com Apple Developer Documentation, este método é chamado exatamente uma vez durante toda a existência do controlador. viewDidLoad é o local principal para a configuração inicial da interface, registro de células e inicialização de dados.
Principais pontos
viewDidLoad é um método de instância de UIViewController que o UIKit chama imediatamente após a View do controlador ser carregada na memória. Neste ponto, todas as propriedades IBOutlet já estão conectadas aos elementos da interface, mas a View ainda não foi adicionada à hierarquia de janelas e não está visível para o usuário. O desenvolvedor sobrescreve este método para realizar a configuração inicial da tela.
O método faz parte do ViewController Lifecycle e vem imediatamente após loadView se a View for criada programaticamente, ou após o carregamento do Storyboard. Em um projeto típico, viewDidLoad é o método mais sobrescrito de UIViewController, pois fornece um ponto seguro para trabalhar com subviews que já existem e estão prontas para configuração.
Um detalhe importante: no momento em que viewDidLoad é chamado, as dimensões da View ainda não correspondem às finais — o Auto Layout não concluiu suas passagens, e o frame pode diferir do esperado. Para cálculos que dependem de dimensões, use viewDidLayoutSubviews.
O momento da chamada de viewDidLoad depende de como o controlador é inicializado. Na maioria dos casos, o UIKit chama este método automaticamente na primeira vez que a propriedade view do controlador é acessada — isso é chamado de mecanismo de lazy-loading do UIViewController.
Quando um NavigationController ou TabBarController exibe sua tela pela primeira vez, o UIKit verifica se a View está carregada. Se não — loadView é chamado (ou carregamento do Storyboard), após o qual viewDidLoad é imediatamente acionado. Este é o cenário padrão e ocorre uma vez para cada instância do controlador.
override func viewDidLoad() {
super.viewDidLoad()
print("View carregada — você pode configurar a interface")
setupUI()
configureTableView()
}
viewDidLoad não é chamado novamente ao retornar à tela pelo botão voltar ou dismiss. Se sua lógica depende da tela aparecer novamente — coloque-a em viewWillAppear. Este é um dos erros conceituais mais comuns: desenvolvedores esperam que viewDidLoad dispare em cada exibição, mas o UIKit o chama apenas uma vez.
Às vezes, desenvolvedores acessam forçadamente a view do controlador para acionar o carregamento antecipadamente: let _ = controller.view. Isso força a chamada de loadView e viewDidLoad antes que o controlador apareça na tela. Esta técnica é usada quando você precisa preparar a View antecipadamente para uma transição suave.
viewDidLoad é destinado a operações de configuração únicas que não dependem se a tela está visível. O uso correto deste método é a chave para uma arquitetura limpa e um comportamento previsível do controlador.
Em viewDidLoad, você registra arquivos nib e classes para UITableView e UICollectionView, configura delegates e define valores iniciais para propriedades dos elementos UI. Como todos os IBOutlet já estão conectados neste ponto, você pode acessar com segurança label.text, imageView.image e outras propriedades das subviews.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.register(
CustomCell.self,
forCellReuseIdentifier: CustomCell.identifier
)
title = "Tela principal"
}
Aqui você cria uma viewModel, inicializa o data source com arrays e assina notificações que devem estar ativas durante toda a vida do controlador. Por exemplo, assinar UIApplication.willEnterForegroundNotification para atualizar dados ao retornar do background é um bom candidato para viewDidLoad. A viewModel na arquitetura iOS moderna atua como uma ponte entre o controlador e a lógica de negócios, e inicializá-la em viewDidLoad garante que os dados estejam prontos quando a tela aparecer pela primeira vez.
Preste atenção especial à configuração do data source para tabelas e coleções. Se sua tabela usa UIFetchedResultsController ou NSFetchedResultsController com Core Data, inicialize o fetch request e o delegate em viewDidLoad. Isso garante que quando a tela aparecer pela primeira vez, a tabela já estará preenchida com dados sem solicitações adicionais.
Em viewDidLoad, você configura os botões da NavigationBar, define o large title, adiciona o search controller e define os botões edit/done. Esses elementos raramente mudam quando a tela é exibida novamente, portanto inicializá-los aqui é ótimo.
Nem todas as operações são apropriadas em viewDidLoad. Algumas ações colocadas neste método levam a consumo excessivo de memória, comportamento incorreto ou bugs quando a tela é exibida novamente.
Evite iniciar requisições de rede cujo resultado afeta apenas a UI. Se a requisição for concluída antes da tela aparecer, o usuário não verá o resultado, e se for concluída depois — os dados podem estar desatualizados. Inicie o carregamento em viewDidLoad, mas atualize a UI em viewWillAppear.
Não realize operações em viewDidLoad que dependam do tamanho e da posição da View. No momento da chamada, o Auto Layout não concluiu suas passagens e o frame pode não ser final. Para cálculos, use viewDidLayoutSubviews ou sobrescreva updateViewConstraints.
Não assine notificações que são relevantes apenas quando a tela está visível. Notificações de teclado, notificações de alteração de conteúdo de controladores filhos — assine-as em viewWillAppear e cancele a assinatura em viewDidDisappear para evitar chamadas desnecessárias e vazamentos.
Não chame métodos que exigem uma tela visível. Por exemplo, tentar mostrar um UIAlertController a partir de viewDidLoad resultará em erro porque a View do controlador ainda não foi adicionada à hierarquia de janelas. Qualquer operação de UI que dependa da janela ou presentedViewController deve ser executada somente após a tela aparecer.
Não inicialize recursos pesados desnecessariamente. Se a tela raramente é mostrada ou os dados não são exibidos imediatamente, adie a criação de objetos que consomem muitos recursos até que sejam realmente necessários. A inicialização lazy de propriedades em Swift é um mecanismo integrado para resolver este problema: uma propriedade com o modificador lazy será criada apenas no primeiro acesso, economizando memória e acelerando o carregamento da tela.
Não use viewDidLoad para operações que devem ser executadas toda vez que a tela aparece. Este é o erro mais fundamental: desenvolvedores iniciantes frequentemente colocam a lógica de atualização de dados em viewDidLoad e se surpreendem que ao retornar de outra tela, a tabela não recarrega. Se uma operação deve se repetir em cada exibição — use viewWillAppear. Se deve executar uma vez por vida útil — use viewDidLoad. Lembre-se desta regra simples para evitar a maioria dos problemas com o ciclo de vida do UIViewController.
Vamos ver três exemplos práticos demonstrando o uso correto de viewDidLoad em projetos reais. Cada exemplo resolve uma tarefa específica de configuração de tela.
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(
PhotoCell.self,
forCellWithReuseIdentifier: PhotoCell.reuseId
)
collectionView.register(
HeaderView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderView.reuseId
)
viewModel.delegate = self
viewModel.fetchInitialPage()
}
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
label.text = "Olá, mundo!"
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
Em viewDidLoad, você também configura elementos exibidos quando não há dados: estado vazio, loader, placeholder. Esses componentes são criados uma vez e reutilizados cada vez que a tela aparece. Ocultar ou mostrar esses elementos é gerenciado em viewWillAppear dependendo dos dados atuais.
override func viewDidLoad() {
super.viewDidLoad()
emptyStateLabel = UILabel()
emptyStateLabel.text = "Sem dados"
emptyStateLabel.textAlignment = .center
emptyStateLabel.isHidden = true
view.addSubview(emptyStateLabel)
activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.hidesWhenStopped = true
view.addSubview(activityIndicator)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleEnterForeground),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
}
@objc private func handleEnterForeground() {
refreshContent()
}
Perguntas frequentes
Em condições normais, não — o UIKit chama viewDidLoad uma vez após carregar a View na memória. Se o controlador for destruído e criado novamente, viewDidLoad será executado para a nova instância.
Sim, absolutamente. Chamar super.viewDidLoad garante que o UIKit realize a configuração interna necessária para o Lifecycle funcionar corretamente. Sempre chame super primeiro dentro do método.
viewDidLoad é chamado uma vez ao carregar a View. viewWillAppear é chamado toda vez antes da tela aparecer. O primeiro é para configuração única, o segundo para atualizar dados e estado.
Operações síncronas pesadas em viewDidLoad bloqueiam a thread principal e atrasam o aparecimento da tela. Cargas assíncronas são aceitáveis, mas ao atualizar a UI após a conclusão, deve-se considerar que a tela pode já estar oculta.
Você não pode chamar viewDidLoad diretamente — o UIKit o chama. Para forçar o carregamento da View, acesse a propriedade controller.view. Isso acionará loadView e viewDidLoad automaticamente.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também