UIViewController — centrální třída iOS aplikace, která spravuje obrazovku a její obsah. Každá obrazovka iPhone nebo iPad je spravována jedním ViewController, který koordinuje zobrazení, životní cyklus a navigaci. Více o architektuře UIKit si přečtěte v oficiální dokumentaci Apple.
Hlavní body
UIViewController — třída z frameworku UIKit, která spravuje hierarchii UIView a koordinuje zobrazení dat na obrazovce. Každá iOS aplikace obsahuje alespoň jeden ViewController — kořenový ovladač okna. Ovladač zpracovává rotace obrazovky, přechody mezi obrazovkami a události životního cyklu.
Architektura MVC (Model-View-Controller) v iOS je implementována právě přes UIViewController: ovladač přijímá data z modelu a aktualizuje zobrazení. ViewController není vizuální prvek — spravuje vlastnost view, která obsahuje hierarchii subview. Podle údajů Apple (2026) obsahuje UIKit více než 40 vestavěných podtříd UIViewController.
První iPhone SDK (2008) obsahoval UIViewController se třemi metodami životního cyklu. Během 18 let Apple přidal podporu pro Container View Controller, adaptivní prezentace, UIViewControllerTransitioningDelegate pro vlastní animace a režim rozdělené obrazovky na iPadu. UIViewController zůstává povinnou součástí pro UIKit aplikace.
Životní cyklus UIViewController — sekvence metod volaných systémem při vytváření, zobrazování a skrývání obrazovky. Pochopení životního cyklu je kritické: nesprávné umístění kódu vede k únikům paměti, zbytečným síťovým požadavkům a blikání rozhraní.
| Metoda | Okamžik volání | Účel |
|---|---|---|
| viewDidLoad | Jednou, po načtení view do paměti | Počáteční nastavení UI, přihlášení k Combine |
| viewWillAppear | Před objevením se obrazovky | Aktualizace dat, skrytí/zobrazení navigation baru |
| viewDidAppear | Po objevení se obrazovky | Spuštění animací, analytika, aktualizace kamery |
| viewWillDisappear | Před opuštěním obrazovky | Uložení konceptů, odhlášení z notifikací |
| viewDidDisappear | Po opuštění obrazovky | Zastavení těžkých procesů, uvolnění zdrojů |
Při prvním zobrazení obrazovky: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. Při opětovném objevení (návrat z jiné obrazovky): viewWillAppear → viewDidAppear. viewDidLoad se volá pouze jednou za životnost ovladače.
Metoda viewDidLoad — hlavní bod nastavení uživatelského rozhraní. Volá se po načtení view do paměti, když jsou všechny IBOutlet již připojeny. Zde se vytvářejí prvky UI programově, nastavují se omezení, načítají se počáteční data.
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)
}
}Ve SwiftUI je tento kód ekvivalentem těla View. Ale UIViewController poskytuje plnou kontrolu nad životním cyklem a optimalizací. bindViewModel používá Combine pro reaktivní přihlášení — data se automaticky aktualizují při změně modelu.
viewWillAppear se volá pokaždé před objevením se obrazovky, i když byla již v paměti. Toto je místo pro aktualizaci dat, která se mohla změnit na jiné obrazovce: opětovné načtení seznamu, aktualizace počítadla notifikací, nastavení navigation baru pro konkrétní obrazovku.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Skryjeme navigation bar na této obrazovce
navigationController?.setNavigationBarHidden(true, animated: animated)
// Aktualizujeme data při návratu z jiné obrazovky
tableView.reloadData()
badgeLabel.text = "\(CartManager.shared.itemCount)"
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Analytika: teprve poté, co uživatel viděl obrazovku
AnalyticsService.shared.logScreenView("Profile")
}Rozdíl mezi viewDidLoad a viewWillAppear je kritický: viewDidLoad se provede jednou a je vhodný pro statické nastavení, viewWillAppear — pokaždé při zobrazení, vhodný pro dynamické aktualizace. Umístění síťových požadavků do viewDidLoad povede k zobrazení zastaralých dat při návratu na obrazovku.
Container View Controller — ViewController, který spravuje jeden nebo více podřízených ViewController. Apple poskytuje tři vestavěné kontejnery: UINavigationController (zásobník obrazovek), UITabBarController (karty) a UISplitViewController (master-detail pro iPad).
UINavigationController organizuje přechody v zásobníku — push přidává obrazovku, pop odebírá. UITabBarController přepíná mezi nezávislými sekcemi aplikace. UISplitViewController zobrazuje dva ovladače vedle sebe na iPadu a jeden na iPhonu. Vývojář může vytvořit vlastní kontejner pomocí addChild.
// Vlastní Container View Controller
final class ContainerViewController: UIViewController {
private let sidebarVC = SidebarViewController()
private let contentVC = ContentViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Přidání podřízeného ovladače
addChild(sidebarVC)
view.addSubview(sidebarVC.view)
sidebarVC.didMove(toParent: self)
addChild(contentVC)
view.addSubview(contentVC.view)
contentVC.didMove(toParent: self)
}
}Správná práce s Container View Controller vyžaduje volání addChild, přidání view a didMove(toParent:) v tomto pořadí. Při odstraňování — willMove(toParent: nil), removeFromSuperview, removeFromParent. Porušení pořadí vede k únikům paměti.
Problém Massive View Controller — když UIViewController obsahuje stovky řádků kódu s obchodní logikou, síťovými požadavky, navigací a UI kódem. Apple si je problému vědom a doporučuje MVVM (Model-View-ViewModel) spolu s Coordinator pro oddělení navigace.
MVVM přesouvá obchodní logiku z ovladače do ViewModel. Controller pouze propojuje ViewModel s View přes Combine nebo delegáta. Coordinator odděluje navigační logiku — vytváření a přechody mezi ovladači — do samostatné třídy. Tento přístup byl zahrnut do nejlepších praktik Apple od roku 2024.
// Coordinator — správa navigace
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)
}
}Výběr mezi UIViewController a SwiftUI View závisí na roku zahájení projektu, požadavcích na přizpůsobení a minimální podporované verzi iOS. UIKit s UIViewController zůstává základem pro projekty zahájené před rokem 2020 a pro aplikace s hlubokým přizpůsobením rozhraní.
SwiftUI je vhodný pro nové projekty s iOS 17+, standardní rozhraní a prototypy. Avšak pro vlastní přechody, práci s kamerou, MapKit, složité CALayer animace je vyžadován UIViewController. Apple doporučuje kombinovat přístupy přes UIHostingController (SwiftUI uvnitř UIKit) a UIViewRepresentable (UIKit uvnitř SwiftUI).
| Scénář | UIKit (UIViewController) | SwiftUI (View) |
|---|---|---|
| Vlastní animace | Plná kontrola přes UIViewPropertyAnimator | Omezená přes Animation |
| Práce s kamerou | AVCaptureSession + UIViewPreview | Přes UIViewControllerRepresentable |
| CollectionView | UICollectionView + UICollectionViewLayout | LazyVGrid/LazyHGrid |
| Adaptace iPad | UISplitViewController + UITraitCollection | NavigationSplitView + sizeClass |
| Rychlost vývoje | Pomalejší (ruční layout) | Rychlejší (deklarativní) |
Často kladené otázky
UIViewController — ovladač, který spravuje obrazovku a její životní cyklus. UIView — zobrazení, které zobrazuje obsah. ViewController obsahuje hierarchii UIView, ale sám není vizuálním prvkem. Jeden ovladač spravuje mnoho zobrazení.
Massive View Controller — antivzor, když UIViewController obsahuje příliš mnoho logiky: data, navigaci, síťové požadavky, animace. Řešení — oddělení kódu do samostatných služeb, koordinátorů a ViewModel (MVVM).
Čtyři způsoby: přes vlastnost při prepare(for:sender:) (Segue), přes delegáta (Delegate), přes uzavření (Closure), přes sdílenou službu. Pro volné propojení se používá Coordinator + Delegate nebo Combine.
Container View Controller — ovladač, který spravuje podřízené ViewController. Příklady: UINavigationController, UITabBarController, UISplitViewController. Nadřazený ovladač přidává podřízené přes addChild, přepíná mezi nimi a spravuje jejich layout.
UIViewController — pro složité vlastní animace, práci s kamerou, mapou, videem, UICollectionView s vlastním layoutem. SwiftUI View — pro standardní rozhraní iOS 13+. Kombinace přes UIHostingController je povolena.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také