ViewController — a essência do controlador de tela no iOS e seu Lifecycle

Autor: IT Sectr Publicado: 2026-02-22 Tempo de leitura: 7 min

UIViewController é a classe central das aplicações iOS, gerenciando a tela e seu conteúdo. Cada tela de iPhone ou iPad é gerenciada por um ViewController, que coordena a exibição, o ciclo de vida e a navegação. Saiba mais sobre a arquitetura do UIKit em documentação oficial da Apple.

Principais Pontos

  • UIViewController — a classe base para gerenciar uma tela no UIKit com seu próprio ciclo de vida
  • viewDidLoad — chamado uma vez, ponto de inicialização da UI e assinatura de dados
  • viewWillAppear — a tela em breve ficará visível, atualização de dados antes da exibição
  • Lifecycle inclui cinco métodos: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • Massive View Controller — o principal antipadrão do iOS, resolvido via MVVM ou Coordinator

O que é um ViewController?

UIViewController é uma classe do framework UIKit que gerencia uma hierarquia de UIView e coordena a exibição de dados na tela. Cada aplicação iOS contém pelo menos um ViewController — o controlador raiz da janela. O controlador lida com rotações de tela, transições entre telas e eventos do ciclo de vida.

A arquitetura MVC (Model-View-Controller) no iOS é implementada precisamente através do UIViewController: o controlador recebe dados do modelo e atualiza a visão. Um ViewController não é um elemento visual — ele gerencia a propriedade view, que contém uma hierarquia de subviews. De acordo com a Apple (2026), o UIKit contém mais de 40 subclasses incorporadas de UIViewController.

O primeiro iPhone SDK (2008) incluía UIViewController com três métodos de ciclo de vida. Ao longo de 18 anos, a Apple adicionou suporte para Container View Controller, apresentações adaptativas, UIViewControllerTransitioningDelegate para animações personalizadas e modo de tela dividida no iPad. UIViewController continua sendo um componente obrigatório para aplicações UIKit.

O ciclo de vida do UIViewController

O ciclo de vida do UIViewController é uma sequência de métodos chamados pelo sistema ao criar, exibir e ocultar uma tela. Compreender o Lifecycle é criticamente importante: a colocação incorreta de código leva a vazamentos de memória, solicitações de rede desnecessárias e cintilação da interface.

MétodoMomento da chamadaPropósito
viewDidLoadUma vez, após a view ser carregada na memóriaConfiguração inicial da UI, assinatura Combine
viewWillAppearAntes da tela aparecerAtualização de dados, ocultar/mostrar barra de navegação
viewDidAppearApós a tela aparecerIniciar animações, análise, atualização de câmera
viewWillDisappearAntes de sair da telaSalvar rascunhos, cancelar assinatura de notificações
viewDidDisappearApós sair da telaParar processos pesados, liberar recursos

Ordem de chamada ao aparecer a tela

Na primeira exibição da tela, a sequência é: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. No reaparecimento (retorno de outra tela): viewWillAppear → viewDidAppear. viewDidLoad é chamado apenas uma vez durante a vida do controlador.

viewDidLoad, init e configuração da UI

O método viewDidLoad é o ponto principal para configurar a interface do usuário. É chamado após a view ser carregada na memória, quando todas as conexões IBOutlet já estão estabelecidas. Aqui, elementos de UI são criados programaticamente, constraints são configurados e dados iniciais são carregados.

swift
final class ProfileViewController: UIViewController {

    private let tableView = UITableView()
    private let viewModel = ProfileViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        bindViewModel()
    }

    private func setupUI() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        tableView.register(ProfileCell.self,
                         forCellReuseIdentifier: ProfileCell.reuseId)
    }

    private func bindViewModel() {
        viewModel.$user
            .receive(on: DispatchQueue.main)
            .sink { [weak self] user in
                self?.title = user.name
            }
            .store(in: &cancellables)
    }
}

No SwiftUI, este código equivale ao corpo da View. Mas o UIViewController oferece controle total sobre o ciclo de vida e a otimização. bindViewModel usa Combine para assinatura reativa — os dados são atualizados automaticamente quando o modelo muda.

viewWillAppear e atualização de dados

viewWillAppear é chamado toda vez antes da tela aparecer, mesmo se já estiver na memória. Este é o local para atualizar dados que podem ter mudado em outra tela: recarregar uma lista, atualizar o emblema de notificações, configurar a barra de navegação para uma tela específica.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Ocultar a barra de navegação nesta tela
    navigationController?.setNavigationBarHidden(true, animated: animated)

    // Atualizar dados ao retornar de outra tela
    tableView.reloadData()
    badgeLabel.text = "\(CartManager.shared.itemCount)"
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // Análise: apenas depois que o usuário viu a tela
    AnalyticsService.shared.logScreenView("Profile")
}

A diferença entre viewDidLoad e viewWillAppear é crítica: viewDidLoad é executado uma vez e é adequado para configuração estática, viewWillAppear é executado toda vez que a tela é exibida e é adequado para atualizações dinâmicas. Colocar solicitações de rede no viewDidLoad resultará na exibição de dados desatualizados ao retornar à tela.

Container View Controller: UINavigationController e UITabBarController

Container View Controller é um ViewController que gerencia um ou mais ViewControllers filhos. A Apple fornece três contêineres incorporados: UINavigationController (pilha de telas), UITabBarController (abas) e UISplitViewController (mestre-detalhe para iPad).

UINavigationController organiza transições em uma pilha — push adiciona uma tela, pop a remove. UITabBarController alterna entre seções independentes da aplicação. UISplitViewController mostra dois controladores lado a lado no iPad e um no iPhone. Um desenvolvedor pode criar um contêiner personalizado via addChild.

swift
// Container View Controller personalizado
final class ContainerViewController: UIViewController {

    private let sidebarVC = SidebarViewController()
    private let contentVC = ContentViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Adicionar um controlador filho
        addChild(sidebarVC)
        view.addSubview(sidebarVC.view)
        sidebarVC.didMove(toParent: self)

        addChild(contentVC)
        view.addSubview(contentVC.view)
        contentVC.didMove(toParent: self)
    }
}

O trabalho correto com Container View Controller requer chamar addChild, adicionar a view e didMove(toParent:) nessa ordem. Ao remover: willMove(toParent: nil), removeFromSuperview, removeFromParent. Violar a sequência leva a vazamentos de memória.

Resolvendo Massive View Controller com MVVM e Coordinator

O problema do Massive View Controller ocorre quando um UIViewController contém centenas de linhas de código com lógica de negócios, solicitações de rede, navegação e código de UI. A Apple reconhece o problema e recomenda MVVM (Model-View-ViewModel) junto com Coordinator para extrair a navegação.

MVVM move a lógica de negócios do controlador para uma ViewModel. O Controller apenas liga a ViewModel à View através de Combine ou um delegado. Coordinator extrai a lógica de navegação — criação e transição entre controladores — em uma classe separada. Esta abordagem foi adotada nas melhores práticas da Apple desde 2024.

swift
// Coordinator — gerenciamento de navegação
protocol Coordinator {
    var childCoordinators: [Coordinator] { get set }
    func start()
}

final class MainCoordinator: Coordinator {

    var childCoordinators = [Coordinator]()
    private let navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func start() {
        let vc = ListViewController()
        vc.didSelectItem = { [weak self] item in
            self?.showDetail(item)
        }
        navigationController.pushViewController(vc, animated: false)
    }

    private func showDetail(_ item: Item) {
        let vc = DetailViewController(item: item)
        navigationController.pushViewController(vc, animated: true)
    }
}

UIViewController vs SwiftUI: quando escolher o quê

A escolha entre UIViewController e SwiftUI View depende do ano de início do projeto, requisitos de personalização e versão mínima suportada do iOS. UIKit com UIViewController continua sendo a base para projetos iniciados antes de 2020 e para aplicações com personalização profunda de interface.

SwiftUI é adequado para novos projetos com iOS 17+, interfaces padrão e protótipos. No entanto, transições personalizadas, trabalho com câmera, MapKit, animações complexas de CALayer requerem UIViewController. A Apple recomenda combinar abordagens através de UIHostingController (SwiftUI dentro de UIKit) e UIViewRepresentable (UIKit dentro de SwiftUI).

CenárioUIKit (UIViewController)SwiftUI (View)
Animação personalizadaControle total via UIViewPropertyAnimatorLimitado através de Animation
Trabalho com câmeraAVCaptureSession + UIViewPreviewAtravés de UIViewControllerRepresentable
CollectionViewUICollectionView + UICollectionViewLayoutLazyVGrid/LazyHGrid
Adaptação iPadUISplitViewController + UITraitCollectionNavigationSplitView + sizeClass
Velocidade de desenvolvimentoMais lento (layout manual)Mais rápido (declarativo)

Perguntas Frequentes

Como o UIViewController difere do UIView?

UIViewController é um controlador que gerencia a tela e seu ciclo de vida. UIView é uma visão que exibe conteúdo. Um ViewController contém uma hierarquia de UIViews mas não é em si um elemento visual. Um controlador gerencia múltiplas visões.

O que é um Massive View Controller?

Massive View Controller é um antipadrão onde UIViewController contém muita lógica: dados, navegação, solicitações de rede, animação. A solução é extrair código em serviços separados, coordenadores e ViewModel (MVVM).

Como passar dados entre ViewControllers?

Quatro maneiras: através de uma propriedade em prepare(for:sender:) (Segue), através de um delegado (Delegate), através de um fechamento (Closure), através de um serviço compartilhado. Para acoplamento fraco, use Coordinator + Delegate ou Combine.

O que é um Container View Controller?

Container View Controller é um controlador que gerencia ViewControllers filhos. Exemplos: UINavigationController, UITabBarController, UISplitViewController. O controlador pai adiciona filhos via addChild, alterna entre eles e gerencia seu layout.

Quando usar UIViewController em vez de SwiftUI View?

UIViewController — para animações personalizadas complexas, trabalho com câmera, mapas, vídeo, UICollectionView com layout personalizado. SwiftUI View — para interfaces padrão no iOS 13+. Combinar via UIHostingController é aceitável.

Resumo

  • UIViewController — a classe central UIKit para gerenciar a tela, hierarquia UIView e ciclo de vida
  • Lifecycle consiste em cinco métodos: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • viewDidLoad — o ponto de configuração inicial da UI, chamado uma vez durante a vida do controlador
  • viewWillAppear — chamado toda vez antes da exibição, adequado para atualizar dados e configurar a barra de navegação
  • Container View Controller (UINavigationController, UITabBarController) gerencia a hierarquia de controladores filhos
  • Massive View Controller é resolvido via MVVM (extração de lógica para ViewModel) e Coordinator (extração de navegação)
  • UIViewController e SwiftUI podem ser combinados via UIHostingController e UIViewRepresentable para aplicações híbridas

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.

Discutir o projeto

Leia também