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 — 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.
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.
| Methode | Aanroepmoment | Doel |
|---|---|---|
| viewDidLoad | Eenmalig, nadat view in het geheugen is geladen | Initiële UI-configuratie, Combine-abonnement |
| viewWillAppear | Vóór het verschijnen van het scherm | Gegevens bijwerken, navigation bar verbergen/tonen |
| viewDidAppear | Na het verschijnen van het scherm | Animaties starten, analyse, camera bijwerken |
| viewWillDisappear | Vóór het verlaten van het scherm | Concepten opslaan, uitschrijven voor meldingen |
| viewDidDisappear | Na het verlaten van het scherm | Zware processen stoppen, bronnen vrijgeven |
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.
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.
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 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.
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 — 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.
// 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.
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.
// 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)
}
}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).
| Scenario | UIKit (UIViewController) | SwiftUI (View) |
|---|---|---|
| Aangepaste animatie | Volledige controle via UIViewPropertyAnimator | Beperkt via Animation |
| Werken met camera | AVCaptureSession + UIViewPreview | Via UIViewControllerRepresentable |
| CollectionView | UICollectionView + UICollectionViewLayout | LazyVGrid/LazyHGrid |
| iPad-aanpassing | UISplitViewController + UITraitCollection | NavigationSplitView + sizeClass |
| Ontwikkelsnelheid | Langzamer (handmatige layout) | Sneller (declaratief) |
Veelgestelde vragen
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.
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).
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.
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.
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
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.
Lees ook