ViewController Lifecycle в iOS: ключові поняття, етапи та методи

Автор: IT Sectr Опубліковано: 2026-03-05 Час читання: 9 хв

ViewController Lifecycle — це послідовність методів, які UIKit викликає автоматично при керуванні екранами в iOS. Згідно з документацією Apple, кожен UIViewController проходить через передбачуваний набір станів: від створення View до її появи та приховування. Розуміння порядку та призначення цих методів — необхідна умова для стабільної роботи iOS-додатку.

Головне

  • ViewController Lifecycle — це шість методів UIViewController, які викликаються UIKit у строгому порядку
  • loadView створює ієрархію View, якщо ви не використовуєте Storyboard
  • viewDidLoad викликається один раз і підходить для початкового налаштування екрана
  • viewWillAppear та viewDidAppear спрацьовують при кожній появі
  • viewWillDisappear та viewDidDisappear — для збереження стану та очищення

Що таке ViewController Lifecycle

ViewController Lifecycle — це набір методів, які UIViewController отримує від UIKit протягом свого існування. Кожен екран в iOS-додатку послідовно проходить через етапи створення, завантаження View, появи на екрані, зникнення та звільнення пам'яті. UIKit автоматично викликає відповідні методи на кожному етапі, а розробник перевизначає їх, додаючи свою логіку.

Архітектура UIViewController закладена в основу UIKit і залишається актуальною навіть в епоху SwiftUI — багато проектів, як і раніше, використовують класичний підхід або гібридну архітектуру. Розуміння Lifecycle дозволяє передбачити, в який момент доступні subviews, коли можна безпечно змінювати layout та які операції виконувати при появі або приховуванні екрана.

Кожен метод життєвого циклу має конкретне призначення: одні викликаються єдиний раз за весь час існування контролера, інші — при кожній появі або зникненні. Змішування логіки між методами призводить до важковловимих багів: витоків пам'яті, некоректного оновлення даних і зайвих запитів до мережі.

Повний цикл методів UIViewController

Шість методів утворюють повний життєвий цикл UIViewController. Порядок їх виклику фіксований і не залежить від способу навігації — push, present або unwind segue дотримуються одного і того ж розкладу.

loadView — створення кореневої View

loadView — перший методу циклу, який викликається, коли View контролера ще не існує. Якщо ви використовуєте Storyboard, UIKit автоматично завантажує View з xib-файлу. При програмному створенні інтерфейсу ви перевизначаєте цей метод, призначаючи кореневу View вручну. У більшості проектів loadView не чіпають — робота ведеться в viewDidLoad.

Перевизначення loadView потрібне тільки в специфічних випадках: коли весь інтерфейс створюється кодом без Storyboard або коли коренева View має бути нестандартного класу. Apple рекомендує не викликати super.loadView при перевизначенні — ви повністю берете створення View на себе.

swift
override func loadView() {
    view = UIView()
    view.backgroundColor = .white
}

viewDidLoad — одноразова ініціалізація

viewDidLoad — найбільш часто використовуваний методу циклу. Він викликається один раз після того, як View завантажена в пам'ять, але ще не відображається на екрані. Тут налаштовують subviews, заповнюють таблиці даними, реєструють комірки та підписуються на сповіщення, які діють весь час життя контролера.

Важлива особливість: viewDidLoad не викликається повторно при повторному показі екрана. Якщо вам потрібно оновлювати дані щоразу при появі — використовуйте viewWillAppear. У viewDidLoad розміщуйте тільки одноразові операції, від яких залежить базова конфігурація.

viewWillAppear — підготовка перед показом

viewWillAppear викликається щоразу безпосередньо перед тим, як View стає видимою для користувача. Цей метод отримує параметр animated, який вказує, чи відбувається поява з анімацією. Тут оновлюють дані, перезавантажують таблиці, налаштовують NavigationBar та приховують або показують елементи залежно від стану додатка.

Використовуйте viewWillAppear для синхронізації стану між екранами: якщо користувач міг змінити дані на попередньому екрані, цей метод — правильне місце для оновлення інтерфейсу. Кожен виклик viewWillAppear передує появі екрана, навіть при поверненні з дочірнього контролера.

viewDidAppear — екран повністю видимий

viewDidAppear сповіщає, що View повністю з'явилася на екрані і всі анімації переходу завершені. До цього моменту екран готовий до взаємодії — користувач бачить повний інтерфейс і може з ним працювати. Цей метод підходить для запуску анімацій, які повинні початися після появи, старту таймерів і трекінгу показів аналітики.

На відміну від viewWillAppear, viewDidAppear гарантує, що екран не тільки видимий, але й повністю промальований. Якщо ви запускаєте анімацію в viewWillAppear, частина кадрів може бути пропущена, оскільки UIKit ще не завершив перехід. Для плавних анімацій використовуйте viewDidAppear.

viewWillDisappear — підготовка до приховування

viewWillDisappear викликається перед зникненням View з екрана — при переході на інший контролер, закритті модального вікна або згортанні додатка. Це правильне місце для збереження стану, відписки від сповіщень, зупинки активних процесів і звільнення ресурсів, які не потрібні, коли екран не видимий.

Важливо пам'ятати: viewWillDisappear не гарантує, що View в підсумку зникне — жест може бути скасований. Тому критичні дані зберігайте також у viewDidDisappear, який викликається тільки після фактичного зникнення.

viewDidDisappear — екран прихований

viewDidDisappear завершує цикл появи та зникнення. Він викликається після того, як View вже прихована з екрана. У цьому методі остаточно зупиняють анімації, видаляють тимчасові об'єкти та підтверджують збереження даних, розпочате в viewWillDisappear.

Цей метод також передує deinit контролера — якщо ваш UIViewController знищується, viewDidDisappear буде останнім методом Lifecycle перед викликом deinit. Використовуйте його для фінального очищення, яке повинно відбутися до знищення об'єкта.

Коли викликається кожен метод

Послідовність виклику залежить від того, як саме з'являється екран: вперше, при поверненні назад або при модальному показі. Розглянемо три основні сценарії з точки зору UIKit.

Порядок при першому відкритті

При першій появі екрана UIKit проходить повний цикл створення: викликаються loadView, потім viewDidLoad, після чого стартує анімація появи. Під час анімації викликається viewWillAppear, а після завершення — viewDidAppear. Це єдиний сценарій, коли всі методи від loadView до viewDidAppear спрацьовують послідовно.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    print("viewDidLoad — View завантажена в пам'ять")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear — скоро з'явиться")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("viewDidAppear — екран повністю видимий")
}

Порядок при поверненні назад

Коли користувач повертається на попередній екран, UIKit не викликає viewDidLoad повторно — View вже завантажена в пам'ять. Натомість спрацьовують тільки viewWillAppear та viewDidAppear на поверненому екрані, а на поточному — viewWillDisappear та viewDidDisappear. loadView та viewDidLoad пропускаються, оскільки екран вже існує в стеку навігації.

Особливості при present та dismiss

Модальний показ підпорядковується тим же правилам: у нового контролера викликається повний цикл при першій появі, а у поточного — viewWillDisappear та viewDidDisappear. При dismiss порядок зворотний: у поверненого контролера знову спрацьовують viewWillAppear та viewDidAppear, а у прихованого — завершальні методи. Ця поведінка єдинообразна для всіх типів переходів в UIKit.

Практичні сценарії використання

Розглянемо чотири ключові сценарії, в яких розуміння Lifecycle безпосередньо впливає на якість коду та користувацький досвід. Для кожного сценарію наведемо приклад із рекомендаціями.

Ініціалізація даних у viewDidLoad

viewDidLoad — місце для первинного налаштування, яке не залежить від видимості екрана. Тут налаштовують collectionView, реєструють nib-файли для комірок, створюють data source та layout. Якщо ви завантажуєте дані з мережі, у viewDidLoad краще тільки ініціювати запит, а оновлювати UI — у viewWillAppear, коли екран готовий до відображення.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(
        MyCell.self,
        forCellReuseIdentifier: MyCell.identifier
    )
    viewModel.loadInitialData()
}

Оновлення контенту в viewWillAppear

Використовуйте viewWillAppear для синхронізації даних щоразу при появі екрана. Наприклад, якщо користувач міг змінити налаштування на попередньому екрані, тут оновлюють відображувані значення, перезавантажують таблицю та коригують стан NavigationBar. Це гарантує, що екран завжди показує актуальні дані при будь-якому сценарії навігації.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
    navigationController?.setNavigationBarHidden(false, animated: animated)
}

Аналітика та анімації в viewDidAppear

viewDidAppear ідеально підходить для запуску анімацій, які повинні початися після того, як користувач побачив екран. Тут же відправляють події аналітики: показ екрана, старт onboarding або початок відтворення відео. Запуск анімацій до завершення переходу призводить до смиканого інтерфейсу — UIKit не встигає підготувати достатню кількість кадрів.

Збереження стану в viewWillDisappear

У viewWillDisappear зберігають чернетки, зупиняють таймери та відписуються від NotificationCenter. Це останній момент, коли екран ще видимий і доступний для операцій, що потребують контексту користувача. Для критичних даних додатково використовують viewDidDisappear як страховку від скасованих жестів.

Типові помилки при роботі з Lifecycle

Неправильне використання методів життєвого циклу — одне з найчастіших джерел багів у iOS-додатках. Розглянемо основні помилки, яких припускаються розробники на різних етапах роботи з UIViewController.

Перша помилка — створення subviews в init або loadView при наявності Storyboard. Якщо ви використовуєте Interface Builder, не перевизначайте loadView без необхідності. Створення View у loadView при наявності розкадровки призводить до ігнорування xib-файлу та порожнього екрана.

Друга помилка — підписка на клавіатурні сповіщення в viewDidLoad без відписки. Якщо ви підписалися на UIResponder.keyboardWillShowNotification, але не відписалися при приховуванні екрана, блок буде викликатися і після deinit контролера — це витік пам'яті з потенційним падінням додатка.

Третя помилка — таймери та мережеві запити, запущені до появи екрана. Завантаження зображень або виконання анімацій, коли View ще не видима — марна трата ресурсів. Перенесіть візуальні оновлення в viewWillAppear або viewDidAppear.

Четверта помилка — збереження даних тільки в viewWillDisappear. При інтерактивному pop-жесті користувач може почати свайп і скасувати його — метод викликався, але екран не зник. Дублюйте критичне збереження в viewDidDisappear або в обробнику applicationDidEnterBackground.

Часто задавані питання

Скільки разів викликається viewDidLoad за час життя контролера?

Один раз — після завантаження View у пам'ять. При повторних появах екрана viewDidLoad не викликається. Якщо потрібно перестворити View, контролер повинен бути знищений і створений заново.

Що буде, якщо не викликати super у viewDidLoad?

UIKit вимагає виклику super.viewDidLoad для коректної роботи життєвого циклу. Без нього можливі проблеми з оновленням layout та обробкою переходів. Завжди викликайте super першим ділом всередині методу.

Чи можна використовувати Storyboard та програмний loadView одночасно?

Не рекомендується. Якщо контролер ініціалізований з Storyboard, UIKit автоматично завантажує View з xib. Перевизначення loadView скасовує цей процес, і ваша розкадровка буде проігнорована.

Як правильно відписуватися від NotificationCenter?

Підписуйтеся в viewDidLoad або viewWillAppear, а відписуйтеся в viewWillDisappear або viewDidDisappear, використовуючи слабке посилання на self, щоб уникнути витоків пам'яті при замиканнях.

Чому viewDidDisappear не викликається при force quit?

Force quit вбиває процес примусово — UIKit не встигає викликати методи Lifecycle. Для збереження даних використовуйте сповіщення UIApplication.willTerminateNotification в AppDelegate.

Підсумки

  • ViewController Lifecycle складається з шести методів, які викликаються UIKit у фіксованому порядку
  • loadView та viewDidLoad спрацьовують один раз при створенні контролера
  • viewWillAppear та viewDidAppear викликаються при кожній появі екрана
  • viewWillDisappear та viewDidDisappear — при кожному приховуванні
  • Кожен метод має конкретне призначення — змішування логіки призводить до багів
  • Підписку на сповіщення завжди балансують відпискою у відповідному методі
  • Використовуйте viewDidAppear для анімацій та аналітики, а viewWillDisappear — для збереження стану

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також