viewDidLoad в iOS: что это, назначение и примеры кода

Автор: IT Sectr Опубликовано: 2026-03-05 Время чтения: 8 мин

viewDidLoad — это первый метод, который UIKit вызывает после загрузки View UIViewController в память. По данным Apple Developer Documentation, этот метод вызывается ровно один раз за всё время существования контроллера. viewDidLoad — основное место для начальной настройки интерфейса, регистрации ячеек и инициализации данных.

Главное

  • viewDidLoad вызывается один раз после загрузки View в память
  • super.viewDidLoad обязателен — без него Lifecycle ломается
  • В этом методе настраивают UI, регистрируют ячейки и создают data source
  • Не вызывается повторно при возврате на экран — используйте viewWillAppear
  • Подходит для одноразовых операций и подписки на постоянные уведомления

Что такое viewDidLoad

viewDidLoad — это метод экземпляра UIViewController, который UIKit вызывает сразу после того, как View контроллера была загружена в оперативную память. К этому моменту все IBOutlet-свойства уже соединены с элементами интерфейса, но View ещё не добавлена в иерарсию окон и не видна пользователю. Разработчик переопределяет этот метод, чтобы выполнить начальную конфигурацию экрана.

Метод является частью ViewController Lifecycle и следует сразу после loadView, если View создаётся программно, или после загрузки из Storyboard. В типичном проекте viewDidLoad — самый часто переопределяемый метод UIViewController, так как он предоставляет безопасную точку для работы с subviews, которые уже существуют и готовы к настройке.

Важная деталь: к моменту вызова viewDidLoad размеры View ещё не соответствуют финальным — Auto Layout не завершил проходов, и frame может отличаться от ожидаемого. Для расчётов, зависящих от размеров, используют viewDidLayoutSubviews.

Когда вызывается viewDidLoad

Тайминг вызова viewDidLoad зависит от того, как инициализируется контроллер. В большинстве случаев UIKit вызывает этот метод автоматически при первом обращении к свойству view контроллера — это называется lazy-loading механизмом UIViewController.

При первом открытии экрана

Когда NavigationController или TabBarController впервые показывает ваш экран, UIKit проверяет, загружена ли View. Если нет — вызывается loadView (или загрузка из Storyboard), после чего немедленно срабатывает viewDidLoad. Это стандартный сценарий, и он происходит однократно для каждого экземпляра контроллера.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    print("View загружена — можно настраивать интерфейс")
    setupUI()
    configureTableView()
}

При возврате на существующий экран

viewDidLoad не вызывается повторно при возврате на экран через back button или dismiss. Если ваша логика зависит от того, что экран появляется снова — размещайте её в viewWillAppear. Это одна из самых частых концептуальных ошибок: разработчики ожидают, что viewDidLoad сработает при каждом показе, но UIKit вызывает его всего один раз.

При forcedViewLoad

Иногда разработчики принудительно вызывают view у контроллера, чтобы инициировать загрузку заранее: let _ = controller.view. Это форсирует вызов loadView и viewDidLoad до того, как контроллер появится на экране. Такой приём используют, когда нужно подготовить View заранее для плавного перехода.

Что делают в viewDidLoad

viewDidLoad предназначен для одноразовых операций настройки, которые не зависят от того, видим ли экран. Правильное использование этого метода — залог чистой архитектуры и предсказуемого поведения контроллера.

Настройка UI-компонентов

В viewDidLoad регистрируют nib-файлы и классы для UITableView и UICollectionView, настраивают делегатов, задают первоначальные значения свойств UI-элементов. Поскольку все IBOutlet к этому моменту уже связаны, можно безопасно обращаться к label.text, imageView.image и другим свойствам subviews.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(
        CustomCell.self,
        forCellReuseIdentifier: CustomCell.identifier
    )
    title = "Главный экран"
}

Инициализация данных и подписки

Здесь создают viewModel, инициализируют data source массивами, подписываются на уведомления, которые должны действовать всё время жизни контроллера. Например, подписка на UIApplication.willEnterForegroundNotification для обновления данных при возврате из фона — правильный кандидат для viewDidLoad. ViewModel в современной iOS-архитектуре выступает связующим звеном между контроллером и бизнес-логикой, и её инициализация именно в viewDidLoad обеспечивает готовность данных к моменту первого появления экрана.

Особое внимание уделите настройке data source для таблиц и коллекций. Если ваша таблица использует UIFetchedResultsController или NSFetchedResultsController с Core Data, инициализируйте fetch request и делегат в viewDidLoad. Это гарантирует, что при первом появлении экрана таблица уже будет заполнена данными без дополнительных запросов.

Настройка навигации

В viewDidLoad конфигурируют кнопки NavigationBar, настраивают large title, добавляют search controller и устанавливают кнопки edit/done. Эти элементы редко меняются при повторных показах экрана, поэтому их инициализация здесь оптимальна.

Чего не стоит делать в viewDidLoad

Не все операции уместны в viewDidLoad. Некоторые действия, помещённые в этот метод, приводят к избыточному потреблению памяти, неправильному поведению или багам при повторных показах экрана.

Избегайте запуска сетевых запросов, результат которых влияет только на UI. Если запрос завершится до появления экрана, пользователь не увидит результат, а если после — данные могут устареть. Инициируйте загрузку в viewDidLoad, но обновляйте UI в viewWillAppear.

Не делайте в viewDidLoad операций, зависимых от размеров и положения View. На момент вызова Auto Layout не завершил проходы, и frame может быть нефинальным. Для расчётов используйте viewDidLayoutSubviews или переопределите updateViewConstraints.

Не подписывайтесь на уведомления, которые действуют только когда экран видим. Клавиатурные уведомления, уведомления об изменении контента дочерних контроллеров — подписывайтесь на них в viewWillAppear и отписывайтесь в viewDidDisappear, чтобы избежать лишних вызовов и утечек.

Не вызывайте методы, требующие видимого экрана. Например, попытка показать UIAlertController из viewDidLoad приведёт к ошибке, так как View контроллера ещё не добавлена в иерархию окон. Любые UI-операции, зависящие от window или presentedViewController, должны выполняться только после появления экрана.

Не инициализируйте тяжёлые ресурсы без необходимости. Если на экран приходят редко или данные отображаются не сразу, отложите создание ресурсоёмких объектов до момента, когда они действительно понадобятся. Lazy-инициализация свойств в Swift — встроенный механизм для решения этой задачи: свойство с модификатором lazy будет создано только при первом обращении к нему, что экономит память и ускоряет загрузку экрана.

Не используйте viewDidLoad для операций, которые должны выполняться при каждом появлении экрана. Это самая фундаментальная ошибка: начинающие разработчики часто размещают логику обновления данных в viewDidLoad и удивляются, что при возврате с другого экрана таблица не перезагружается. Если операция должна повторяться при каждом показе — используйте viewWillAppear. Если должна выполниться один раз за время жизни — viewDidLoad. Запомните это простое правило, чтобы избежать большинства проблем с жизненным циклом UIViewController.

Примеры кода с viewDidLoad

Рассмотрим три практических примера, демонстрирующих правильное использование viewDidLoad в реальных проектах. Каждый пример решает конкретную задачу настройки экрана.

Пример 1: настройка коллекции с кастомными ячейками

swift
override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.register(
        PhotoCell.self,
        forCellWithReuseIdentifier: PhotoCell.reuseId
    )
    collectionView.register(
        HeaderView.self,
        forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
        withReuseIdentifier: HeaderView.reuseId
    )
    viewModel.delegate = self
    viewModel.fetchInitialPage()
}

Пример 2: настройка констрейнтов программно

swift
override func viewDidLoad() {
    super.viewDidLoad()
    let label = UILabel()
    label.text = "Привет, мир!"
    label.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(label)

    NSLayoutConstraint.activate([
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    ])
}

Пример 3: настройка пустого состояния и лоадера

В viewDidLoad также настраивают элементы, отображаемые при отсутствии данных: пустое состояние, лоадер, placeholder. Эти компоненты создаются один раз и переиспользуются при каждом появлении экрана. Сокрытие или показ этих элементов управляется в viewWillAppear в зависимости от актуальных данных.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    emptyStateLabel = UILabel()
    emptyStateLabel.text = "Нет данных"
    emptyStateLabel.textAlignment = .center
    emptyStateLabel.isHidden = true
    view.addSubview(emptyStateLabel)

    activityIndicator = UIActivityIndicatorView(style: .medium)
    activityIndicator.hidesWhenStopped = true
    view.addSubview(activityIndicator)
}

Пример 4: подписка на уведомления приложения

swift
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleEnterForeground),
        name: UIApplication.willEnterForegroundNotification,
        object: nil
    )
}

@objc private func handleEnterForeground() {
    refreshContent()
}

Часто задаваемые вопросы

Может ли viewDidLoad вызываться более одного раза?

В нормальных условиях нет — UIKit вызывает viewDidLoad один раз после загрузки View в память. Если контроллер уничтожается и создаётся заново, viewDidLoad сработает для нового экземпляра.

Нужно ли вызывать super.viewDidLoad?

Да, обязательно. Вызов super.viewDidLoad гарантирует, что UIKit выполнит внутреннюю настройку, необходимую для корректной работы Lifecycle. Всегда вызывайте super первым делом внутри метода.

В чём разница между viewDidLoad и viewWillAppear?

viewDidLoad вызывается один раз при загрузке View. viewWillAppear вызывается каждый раз перед появлением экрана. Первый — для одноразовой настройки, второй — для обновления данных и состояния.

Можно ли делать в viewDidLoad тяжелые операции?

Тяжёлые синхронные операции в viewDidLoad блокируют main thread и задерживают появление экрана. Асинхронные загрузки допустимы, но обновлять UI по их завершению нужно с учётом, что экран может быть уже скрыт.

Как вызвать viewDidLoad принудительно?

Напрямую viewDidLoad вызвать нельзя — его вызывает UIKit. Чтобы форсировать загрузку View, обратитесь к свойству controller.view. Это запустит loadView и viewDidLoad автоматически.

Итоги

  • viewDidLoad — метод одноразовой настройки UIViewController после загрузки View в память
  • Вызывается один раз за время жизни контроллера при первом обращении к View
  • Подходит для регистрации ячеек, настройки делегатов, инициализации viewModel
  • Всегда вызывайте super.viewDidLoad для корректной работы Lifecycle
  • Не используйте viewDidLoad для операций, зависимых от размеров View
  • Для обновления данных при каждом появлении используйте viewWillAppear
  • Подписка на постоянные уведомления — уместна, на временные — в viewWillAppear

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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