ViewController — esența, controlerul de ecran în iOS și ciclul său de viață

Autor: IT Sectr Publicat: 2026-02-22 Timp de citire: 7 min

UIViewController — clasa centrală a aplicației iOS, care gestionează ecranul și conținutul său. Fiecare ecran al iPhone-ului sau iPad-ului este gestionat de un ViewController care coordonează afișarea, ciclul de viață și navigația. Citiți mai multe despre arhitectura UIKit în documentația oficială Apple.

Puncte principale

  • UIViewController — clasa de bază pentru gestionarea ecranului în UIKit cu propriul ciclu de viață
  • viewDidLoad — apelată o dată, punct de inițializare UI și abonare la date
  • viewWillAppear — ecranul va deveni curând vizibil, actualizarea datelor înainte de afișare
  • Ciclul de viață include cinci metode: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • Massive View Controller — principalul anti-pattern iOS, rezolvat prin MVVM sau Coordinator

Ce este ViewController?

UIViewController — o clasă din framework-ul UIKit care gestionează ierarhia UIView și coordonează afișarea datelor pe ecran. Fiecare aplicație iOS conține cel puțin un ViewController — controlerul rădăcină al ferestrei. Controlerul gestionează rotațiile ecranului, tranzițiile între ecrane și evenimentele ciclului de viață.

Arhitectura MVC (Model-View-Controller) în iOS este implementată exact prin UIViewController: controlerul primește date de la model și actualizează vizualizarea. ViewController nu este un element vizual — gestionează proprietatea view, care conține ierarhia subview-urilor. Conform datelor Apple (2026), UIKit conține peste 40 de subclase încorporate de UIViewController.

Primul iPhone SDK (2008) includea UIViewController cu trei metode ale ciclului de viață. În 18 ani, Apple a adăugat suport pentru Container View Controller, prezentări adaptive, UIViewControllerTransitioningDelegate pentru animații personalizate și modul ecran divizat pe iPad. UIViewController rămâne o componentă obligatorie pentru aplicațiile UIKit.

Ciclul de viață al UIViewController

Ciclul de viață al UIViewController — o secvență de metode apelate de sistem la crearea, afișarea și ascunderea ecranului. Înțelegerea ciclului de viață este critică: plasarea incorectă a codului duce la scurgeri de memorie, solicitări de rețea inutile și pâlpâirea interfeței.

MetodăMomentul apelăriiDestinație
viewDidLoadO dată, după încărcarea view în memorieConfigurare inițială UI, abonare Combine
viewWillAppearÎnainte de apariția ecranuluiActualizare date, ascundere/afișare navigation bar
viewDidAppearDupă apariția ecranuluiPornire animații, analitică, actualizare cameră
viewWillDisappearÎnainte de părăsirea ecranuluiSalvare schițe, dezabonare de la notificări
viewDidDisappearDupă părăsirea ecranuluiOprire procese grele, eliberare resurse

Ordinea apelării la apariția ecranului

La prima afișare a ecranului, secvența: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. La reapariție (revenire de pe alt ecran): viewWillAppear → viewDidAppear. viewDidLoad este apelată doar o dată pe durata de viață a controlerului.

viewDidLoad, init și configurarea UI

Metoda viewDidLoad — punctul principal de configurare a interfeței de utilizator. Apelată după încărcarea view în memorie, când toate IBOutlet-urile sunt deja conectate. Aici sunt create elementele UI programatic, configurate constrângerile, încărcate datele inițiale.

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

În SwiftUI, acest cod este echivalentul corpului View. Dar UIViewController oferă control complet asupra ciclului de viață și optimizării. bindViewModel folosește Combine pentru abonare reactivă — datele se actualizează automat la schimbarea modelului.

viewWillAppear și actualizarea datelor

viewWillAppear este apelată de fiecare dată înainte de apariția ecranului, chiar dacă acesta era deja în memorie. Acesta este locul pentru actualizarea datelor care s-ar fi putut schimba pe un alt ecran: reîncărcarea listei, actualizarea contorului de notificări, configurarea navigation bar pentru ecranul specific.

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

    // Ascunde bara de navigare pe acest ecran
    navigationController?.setNavigationBarHidden(true, animated: animated)

    // Actualizează datele la revenirea de pe alt ecran
    tableView.reloadData()
    badgeLabel.text = "\(CartManager.shared.itemCount)"
}

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

    // Analitică: doar după ce utilizatorul a văzut ecranul
    AnalyticsService.shared.logScreenView("Profile")
}

Diferența dintre viewDidLoad și viewWillAppear este critică: viewDidLoad se execută o dată și este potrivită pentru configurare statică, viewWillAppear — de fiecare dată la afișare, potrivită pentru actualizări dinamice. Plasarea solicitărilor de rețea în viewDidLoad va duce la afișarea datelor învechite la revenirea pe ecran.

Container View Controller: UINavigationController și UITabBarController

Container View Controller — un ViewController care gestionează unul sau mai multe ViewController-uri copil. Apple oferă trei containere încorporate: UINavigationController (stivă de ecrane), UITabBarController (file) și UISplitViewController (master-detail pentru iPad).

UINavigationController organizează tranzițiile într-o stivă — push adaugă un ecran, pop îl elimină. UITabBarController comută între secțiunile independente ale aplicației. UISplitViewController afișează două controlere unul lângă altul pe iPad și unul pe iPhone. Dezvoltatorul poate crea propriul container prin addChild.

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

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

    override func viewDidLoad() {
        super.viewDidLoad()

        // Adăugarea controlerului copil
        addChild(sidebarVC)
        view.addSubview(sidebarVC.view)
        sidebarVC.didMove(toParent: self)

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

Lucrul corect cu Container View Controller necesită apelarea addChild, adăugarea view și didMove(toParent:) în această ordine. La eliminare — willMove(toParent: nil), removeFromSuperview, removeFromParent. Încălcarea ordinii duce la scurgeri de memorie.

Rezolvarea Massive View Controller prin MVVM și Coordinator

Problema Massive View Controller — când UIViewController conține sute de linii de cod cu logică de afaceri, solicitări de rețea, navigație și cod UI. Apple este conștientă de problemă și recomandă MVVM (Model-View-ViewModel) împreună cu Coordinator pentru separarea navigației.

MVVM mută logica de afaceri din controler în ViewModel. Controller doar conectează ViewModel-ul cu View-ul prin Combine sau delegat. Coordinator separă logica de navigație — crearea și tranzițiile între controlere — într-o clasă separată. Această abordare a fost introdusă în cele mai bune practici Apple din 2024.

swift
// Coordinator — gestionarea navigației
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: când să alegi ce

Alegerea între UIViewController și SwiftUI View depinde de anul începerii proiectului, cerințele de personalizare și versiunea minimă de iOS suportată. UIKit cu UIViewController rămâne baza pentru proiectele începute înainte de 2020 și pentru aplicațiile cu personalizare profundă a interfeței.

SwiftUI este potrivit pentru proiecte noi cu iOS 17+, interfețe standard și prototipuri. Totuși, pentru tranziții personalizate, lucru cu camera, MapKit, animații complexe CALayer este necesar UIViewController. Apple recomandă combinarea abordărilor prin UIHostingController (SwiftUI în UIKit) și UIViewRepresentable (UIKit în SwiftUI).

ScenariuUIKit (UIViewController)SwiftUI (View)
Animație personalizatăControl complet prin UIViewPropertyAnimatorLimitat prin Animation
Lucru cu cameraAVCaptureSession + UIViewPreviewPrin UIViewControllerRepresentable
CollectionViewUICollectionView + UICollectionViewLayoutLazyVGrid/LazyHGrid
Adaptare iPadUISplitViewController + UITraitCollectionNavigationSplitView + sizeClass
Viteză de dezvoltareMai lentă (layout manual)Mai rapidă (declarativ)

Întrebări frecvente

Cu ce diferă UIViewController de UIView?

UIViewController — controler care gestionează ecranul și ciclul său de viață. UIView — vizualizare care afișează conținut. ViewController conține o ierarhie UIView, dar nu este el însuși un element vizual. Un controler gestionează mai multe vizualizări.

Ce este Massive View Controller?

Massive View Controller — un anti-pattern când UIViewController conține prea multă logică: date, navigație, solicitări de rețea, animații. Soluția — separarea codului în servicii separate, coordonatori și ViewModel (MVVM).

Cum se transmit date între ViewController-uri?

Patru moduri: prin proprietate la prepare(for:sender:) (Segue), prin delegat (Delegate), prin închidere (Closure), printr-un serviciu comun. Pentru cuplare slabă se utilizează Coordinator + Delegate sau Combine.

Ce este Container View Controller?

Container View Controller — un controler care gestionează ViewController-uri copil. Exemple: UINavigationController, UITabBarController, UISplitViewController. Controlerul părinte adaugă copiii prin addChild, comută între ei și gestionează layout-ul lor.

Când să folosești UIViewController în loc de SwiftUI View?

UIViewController — pentru animații personalizate complexe, lucru cu camera, hartă, video, UICollectionView cu layout personalizat. SwiftUI View — pentru interfețe standard iOS 13+. Combinarea prin UIHostingController este permisă.

Rezumat

  • UIViewController — clasa centrală UIKit pentru gestionarea ecranului, ierarhiei UIView și ciclului de viață
  • Ciclul de viață constă din cinci metode: viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear
  • viewDidLoad — punctul de configurare inițială UI, apelată o dată pe durata de viață a controlerului
  • viewWillAppear — apelată de fiecare dată înainte de afișare, potrivită pentru actualizarea datelor și configurarea navigation bar
  • Container View Controller (UINavigationController, UITabBarController) gestionează ierarhia controlerelor copil
  • Massive View Controller se rezolvă prin MVVM (separarea logicii în ViewModel) și Coordinator (separarea navigației)
  • UIViewController și SwiftUI pot fi combinate prin UIHostingController și UIViewRepresentable pentru aplicații hibride

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și