ViewController — podstata, ovladač obrazovky v iOS a jeho životní cyklus

Autor: IT Sectr Publikováno: 2026-02-22 Doba čtení: 7 min

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 — základní třída pro správu obrazovky v UIKit s vlastním životním cyklem
  • viewDidLoad — volá se jednou, bod inicializace UI a přihlášení k datům
  • viewWillAppear — obrazovka se brzy stane viditelnou, aktualizace dat před zobrazením
  • Životní cyklus zahrnuje pět metod: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • Massive View Controller — hlavní antivzor iOS, řeší se pomocí MVVM nebo Coordinator

Co je ViewController?

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

Ž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í.

MetodaOkamžik voláníÚčel
viewDidLoadJednou, po načtení view do pamětiPočáteční nastavení UI, přihlášení k Combine
viewWillAppearPřed objevením se obrazovkyAktualizace dat, skrytí/zobrazení navigation baru
viewDidAppearPo objevení se obrazovkySpuštění animací, analytika, aktualizace kamery
viewWillDisappearPřed opuštěním obrazovkyUložení konceptů, odhlášení z notifikací
viewDidDisappearPo opuštění obrazovkyZastavení těžkých procesů, uvolnění zdrojů

Pořadí volání při objevení se obrazovky

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.

viewDidLoad, init a nastavení UI

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.

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

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 a aktualizace dat

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.

swift
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: UINavigationController a UITabBarController

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.

swift
// 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.

Řešení Massive View Controller pomocí MVVM a Coordinator

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.

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

UIViewController vs SwiftUI: kdy co vybrat

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í animacePlná kontrola přes UIViewPropertyAnimatorOmezená přes Animation
Práce s kamerouAVCaptureSession + UIViewPreviewPřes UIViewControllerRepresentable
CollectionViewUICollectionView + UICollectionViewLayoutLazyVGrid/LazyHGrid
Adaptace iPadUISplitViewController + UITraitCollectionNavigationSplitView + sizeClass
Rychlost vývojePomalejší (ruční layout)Rychlejší (deklarativní)

Často kladené otázky

Čím se liší UIViewController od UIView?

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í.

Co je Massive View Controller?

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

Jak předat data mezi ViewController?

Č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.

Co je Container View Controller?

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.

Kdy použít UIViewController místo SwiftUI View?

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í

  • UIViewController — centrální třída UIKit pro správu obrazovky, hierarchie UIView a životního cyklu
  • Životní cyklus se skládá z pěti metod: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • viewDidLoad — bod počátečního nastavení UI, volá se jednou za životnost ovladače
  • viewWillAppear — volá se pokaždé před zobrazením, vhodný pro aktualizaci dat a nastavení navigation baru
  • Container View Controller (UINavigationController, UITabBarController) spravuje hierarchii podřízených ovladačů
  • Massive View Controller se řeší pomocí MVVM (přesun logiky do ViewModel) a Coordinator (přesun navigace)
  • UIViewController a SwiftUI lze kombinovat přes UIHostingController a UIViewRepresentable pro hybridní aplikace

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í.

Prodiskutovat projekt

Přečtěte si také