ViewController — de essentie, schermcontroller in iOS en zijn levenscyclus

Auteur: IT Sectr Gepubliceerd: 2026-02-22 Leestijd: 7 min

UIViewController — de centrale klasse van iOS-applicaties, die het scherm en de inhoud ervan beheert. Elk scherm van een iPhone of iPad wordt beheerd door één ViewController, die de weergave, levenscyclus en navigatie coördineert. Lees meer over de UIKit-architectuur in de officiële Apple-documentatie.

Belangrijkste punten

  • UIViewController — de basisklasse voor schermbeheer in UIKit met een eigen levenscyclus
  • viewDidLoad — eenmalig aangeroepen, het punt voor UI-initialisatie en data-abonnement
  • viewWillAppear — het scherm wordt binnenkort zichtbaar, gegevens bijwerken vóór weergave
  • Levenscyclus omvat vijf methoden: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • Massive View Controller — het belangrijkste anti-patroon in iOS, opgelost via MVVM of Coordinator

Wat is een ViewController?

UIViewController — een klasse uit het UIKit-framework die de UIView-hiërarchie beheert en de weergave van gegevens op het scherm coördineert. Elke iOS-applicatie bevat minimaal één ViewController — de rootcontroller van het venster. De controller verwerkt schermrotaties, overgangen tussen schermen en levenscyclusgebeurtenissen.

De MVC-architectuur (Model-View-Controller) in iOS wordt precies via UIViewController geïmplementeerd: de controller ontvangt gegevens van het model en werkt de weergave bij. ViewController is geen visueel element — het beheert de view-eigenschap die de subview-hiërarchie bevat. Volgens Apple-gegevens (2026) bevat UIKit meer dan 40 ingebouwde subklassen van UIViewController.

De eerste iPhone SDK (2008) bevatte UIViewController met drie levenscyclusmethoden. In 18 jaar heeft Apple ondersteuning toegevoegd voor Container View Controller, adaptieve presentaties, UIViewControllerTransitioningDelegate voor aangepaste animaties en de gesplitste schermmodus op iPad. UIViewController blijft een verplicht onderdeel voor UIKit-applicaties.

Levenscyclus van UIViewController

De levenscyclus van UIViewController — een reeks methoden die door het systeem worden aangeroepen bij het maken, weergeven en verbergen van het scherm. Het begrijpen van de levenscyclus is van cruciaal belang: verkeerde plaatsing van code leidt tot geheugenlekken, onnodige netwerkverzoeken en flikkerende interfaces.

MethodeAanroepmomentDoel
viewDidLoadEenmalig, nadat view in het geheugen is geladenInitiële UI-configuratie, Combine-abonnement
viewWillAppearVóór het verschijnen van het schermGegevens bijwerken, navigation bar verbergen/tonen
viewDidAppearNa het verschijnen van het schermAnimaties starten, analyse, camera bijwerken
viewWillDisappearVóór het verlaten van het schermConcepten opslaan, uitschrijven voor meldingen
viewDidDisappearNa het verlaten van het schermZware processen stoppen, bronnen vrijgeven

Aanroepvolgorde bij het verschijnen van het scherm

Bij de eerste weergave van het scherm: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. Bij opnieuw verschijnen (terugkeer van een ander scherm): viewWillAppear → viewDidAppear. viewDidLoad wordt slechts één keer aangeroepen tijdens de levensduur van de controller.

viewDidLoad, init en UI-configuratie

De methode viewDidLoad — het belangrijkste punt voor het configureren van de gebruikersinterface. Wordt aangeroepen nadat view in het geheugen is geladen, wanneer alle IBOutlet's al zijn verbonden. Hier worden UI-elementen programmatisch gemaakt, constraints geconfigureerd en initiële gegevens geladen.

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)
    }
}

In SwiftUI is deze code het equivalent van de View-body. Maar UIViewController geeft volledige controle over de levenscyclus en optimalisatie. bindViewModel gebruikt Combine voor reactief abonnement — gegevens worden automatisch bijgewerkt wanneer het model verandert.

viewWillAppear en gegevens bijwerken

viewWillAppear wordt telkens aangeroepen voordat het scherm verschijnt, zelfs als het al in het geheugen was. Dit is de plaats voor het bijwerken van gegevens die op een ander scherm kunnen zijn gewijzigd: de lijst opnieuw laden, de meldingenteller bijwerken, de navigation bar voor een specifiek scherm configureren.

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

    // Navigation bar verbergen op dit scherm
    navigationController?.setNavigationBarHidden(true, animated: animated)

    // Gegevens bijwerken bij terugkeer van een ander scherm
    tableView.reloadData()
    badgeLabel.text = "\(CartManager.shared.itemCount)"
}

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

    // Analyse: pas nadat de gebruiker het scherm heeft gezien
    AnalyticsService.shared.logScreenView("Profile")
}

Het verschil tussen viewDidLoad en viewWillAppear is cruciaal: viewDidLoad wordt eenmalig uitgevoerd en is geschikt voor statische configuratie, viewWillAppear — telkens bij weergave, geschikt voor dynamische updates. Het plaatsen van netwerkverzoeken in viewDidLoad leidt tot het tonen van verouderde gegevens bij terugkeer naar het scherm.

Container View Controller: UINavigationController en UITabBarController

Container View Controller — een ViewController die een of meer onderliggende ViewControllers beheert. Apple biedt drie ingebouwde containers: UINavigationController (schermstack), UITabBarController (tabbladen) en UISplitViewController (master-detail voor iPad).

UINavigationController organiseert overgangen in een stack — push voegt een scherm toe, pop verwijdert het. UITabBarController schakelt tussen onafhankelijke secties van de applicatie. UISplitViewController toont twee controllers naast elkaar op iPad en één op iPhone. De ontwikkelaar kan zijn eigen container maken via addChild.

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

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

    override func viewDidLoad() {
        super.viewDidLoad()

        // Onderliggende controller toevoegen
        addChild(sidebarVC)
        view.addSubview(sidebarVC.view)
        sidebarVC.didMove(toParent: self)

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

Correct werken met Container View Controller vereist het aanroepen van addChild, het toevoegen van view en didMove(toParent:) in deze volgorde. Bij verwijderen — willMove(toParent: nil), removeFromSuperview, removeFromParent. Het schenden van de volgorde leidt tot geheugenlekken.

Massive View Controller oplossen met MVVM en Coordinator

Het probleem van Massive View Controller — wanneer UIViewController honderden regels code bevat met bedrijfslogica, netwerkverzoeken, navigatie en UI-code. Apple is zich bewust van het probleem en beveelt MVVM (Model-View-ViewModel) aan samen met Coordinator voor het scheiden van navigatie.

MVVM verplaatst bedrijfslogica van de controller naar ViewModel. De Controller verbindt alleen ViewModel met View via Combine of delegate. Coordinator scheidt navigatielogica — het maken van en overgangen tussen controllers — in een aparte klasse. Deze aanpak is sinds 2024 opgenomen in de beste praktijken van Apple.

swift
// Coordinator — navigatiebeheer
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: wanneer wat te kiezen

De keuze tussen UIViewController en SwiftUI View hangt af van het startjaar van het project, de aanpassingsvereisten en de minimale ondersteunde iOS-versie. UIKit met UIViewController blijft de basis voor projecten die vóór 2020 zijn gestart en voor applicaties met diepe interface-aanpassing.

SwiftUI is geschikt voor nieuwe projecten met iOS 17+, standaardinterfaces en prototypes. Voor aangepaste overgangen, werken met camera, MapKit, complexe CALayer-animaties is echter UIViewController vereist. Apple raadt aan om benaderingen te combineren via UIHostingController (SwiftUI binnen UIKit) en UIViewRepresentable (UIKit binnen SwiftUI).

ScenarioUIKit (UIViewController)SwiftUI (View)
Aangepaste animatieVolledige controle via UIViewPropertyAnimatorBeperkt via Animation
Werken met cameraAVCaptureSession + UIViewPreviewVia UIViewControllerRepresentable
CollectionViewUICollectionView + UICollectionViewLayoutLazyVGrid/LazyHGrid
iPad-aanpassingUISplitViewController + UITraitCollectionNavigationSplitView + sizeClass
OntwikkelsnelheidLangzamer (handmatige layout)Sneller (declaratief)

Veelgestelde vragen

Waarin verschilt UIViewController van UIView?

UIViewController — controller die het scherm en zijn levenscyclus beheert. UIView — weergave die inhoud toont. ViewController bevat een UIView-hiërarchie, maar is zelf geen visueel element. Eén controller beheert meerdere weergaven.

Wat is Massive View Controller?

Massive View Controller — een anti-patroon waarbij UIViewController te veel logica bevat: gegevens, navigatie, netwerkverzoeken, animaties. Oplossing — code scheiden in aparte services, coördinatoren en ViewModel (MVVM).

Hoe gegevens overdragen tussen ViewControllers?

Vier manieren: via een eigenschap bij prepare(for:sender:) (Segue), via Delegate, via Closure, via een gedeelde service. Voor losse koppeling wordt Coordinator + Delegate of Combine gebruikt.

Wat is Container View Controller?

Container View Controller — een controller die onderliggende ViewControllers beheert. Voorbeelden: UINavigationController, UITabBarController, UISplitViewController. De oudercontroller voegt kinderen toe via addChild, schakelt tussen hen en beheert hun layout.

Wanneer UIViewController gebruiken in plaats van SwiftUI View?

UIViewController — voor complexe aangepaste animaties, werken met camera, kaart, video, UICollectionView met aangepaste layout. SwiftUI View — voor standaardinterfaces iOS 13+. Combineren via UIHostingController is toegestaan.

Samenvatting

  • UIViewController — de centrale UIKit-klasse voor het beheren van scherm, UIView-hiërarchie en levenscyclus
  • Levenscyclus bestaat uit vijf methoden: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • viewDidLoad — het punt voor initiële UI-configuratie, eenmalig aangeroepen tijdens de levensduur van de controller
  • viewWillAppear — telkens vóór weergave aangeroepen, geschikt voor gegevensbijwerking en navigation bar-configuratie
  • Container View Controller (UINavigationController, UITabBarController) beheert de hiërarchie van onderliggende controllers
  • Massive View Controller wordt opgelost via MVVM (logica scheiden in ViewModel) en Coordinator (navigatie scheiden)
  • UIViewController en SwiftUI kunnen worden gecombineerd via UIHostingController en UIViewRepresentable voor hybride applicaties

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook