Перейти к содержимому
Учи.Онлайн Выбрать школу
Статья

UIKit для iOS-разработчика: вёрстка экранов, Auto Layout и совместная работа со SwiftUI

UIKit — фреймворк Apple, на котором собран интерфейс большинства существующих iOS-приложений. Разработчик на UIKit создаёт контроллер экрана, расставляет элементы констрейнтами Auto Layout, выводит данные в UITableView или UICollectionView, настраивает переходы и следит, чтобы закрытый экран освобождал память. Для уверенной работы нужно понимать жизненный цикл UIViewController, правила Auto Layout, переиспользование ячеек и diffable data source, а также уметь встроить экран SwiftUI в проект на UIKit и обратно.

Автор: редакция Учи.ОнлайнОтветственный редактор: Дмитрий Игнатьев
Содержание
Иллюстрация к статье: UIKit для iOS-разработчика: вёрстка экранов, Auto Layout и совместная работа со SwiftUI

Частое заблуждение — что после появления SwiftUI учить UIKit поздно. Новые экраны действительно чаще пишут на SwiftUI, но приложение банка или маркетплейса обычно старше него, и первые задачи новичка в такой команде — поправить вёрстку карточки товара, добавить ячейку в список заказов, понять, почему экран не уходит из памяти. Язык Swift и сам SwiftUI разобраны в соседней статье сайта, здесь речь о работе руками в UIKit.

Когда UIKit всё ещё нужен

UIKit остаётся рабочим инструментом в трёх случаях. Первый — готовый код: сотни контроллеров старого проекта ради моды не переписывают. Второй — точный контроль: длинная лента с разнородными ячейками и сложные анимации переходов на UIKit ведут себя предсказуемее. Третий — компоненты без полного аналога в SwiftUI: их оборачивают в UIViewRepresentable, и код внутри всё равно пишут на UIKit. Для своего небольшого приложения с нуля проще начать со SwiftUI, но для работы в iOS-команде UIKit нужно хотя бы читать.

Жизненный цикл UIViewController и сцены

Экран в UIKit — наследник UIViewController, и система вызывает его методы в строгом порядке. В viewDidLoad один раз создают подвиды, констрейнты и запускают загрузку данных. В viewWillAppear обновляют то, что могло измениться, пока экран был скрыт, например счётчик корзины. В viewDidLayoutSubviews уже известны реальные размеры. В viewDidDisappear останавливают таймеры и видео. Типичная ошибка — считать размеры в viewDidLoad, где ширина ещё не та, что на устройстве.

Уровнем выше — жизненный цикл приложения. Старые учебники создают окно в AppDelegate, но с iOS 13 оно живёт в сцене UIWindowScene, а события «стал активным» и «ушёл в фон» получает SceneDelegate. В техзаметке TN3187 «Migrating to the UIKit scene-based life cycle» Apple пишет: в следующем крупном выпуске после iOS 26 при сборке с актуальным SDK сценовый жизненный цикл станет обязательным, а приложение без него не запустится; уже iOS 26 предупреждает об этом в консоли строкой «UIScene lifecycle will soon be required». Признаки старой схемы там же: в Info.plist нет ключа UIApplicationSceneManifest с конфигурациями, а AppDelegate не реализует application(_:configurationForConnecting:options:). Для учащегося вывод прямой: проект из урока, где окно создаётся в AppDelegate, на новом SDK может не открыться. Окно переносят в scene(_:willConnectTo:options:), а код из applicationDidBecomeActive и соседних методов — в sceneDidBecomeActive и его аналоги в SceneDelegate.

Auto Layout: констрейнты без конфликтов

Auto Layout задаёт положение правилами: левый край кнопки на 16 точек правее безопасной области, высота 44, отступ до поля ввода 12. Правил должно хватать, чтобы положение и размер определились однозначно. Если они противоречат друг другу, в консоли появляется Unable to simultaneously satisfy constraints, и UIKit сам отключает одно из правил — не обязательно то, что выбрали бы вы.

Чаще всего спотыкаются на трёх вещах. При вёрстке кодом забывают translatesAutoresizingMaskIntoConstraints = false, и автоматические правила конфликтуют с вашими. Не задают приоритеты сопротивления сжатию, и из двух длинных подписей в строке обрезается не та. Привязывают элементы к краям экрана, а не к safeAreaLayoutGuide, и кнопка уезжает под «чёлку». Многие разметки проще собрать в UIStackView: он сам расставляет констрейнты между вложенными элементами.

Списки: UITableView, UICollectionView и diffable data source

UITableView показывает вертикальный список, UICollectionView — любую сетку. Ячейки переиспользуются: ушедшая за край экрана ячейка получает данные другой строки. Если в одной ячейке вы скрыли значок «скидка» и не вернули его в остальных случаях, он пропадёт и у соседних товаров, поэтому ячейку настраивают полностью при каждой выдаче.

Diffable data source заменяет ручные insertRows и deleteRows: вы описываете снимок — разделы и идентификаторы элементов, — а UIKit сам вычисляет разницу и анимирует её. Ошибка новичка — делать идентификатором всю модель: при смене цены элемент считается новым, и ячейка мигает, удаляясь и вставляясь заново. Надёжнее хранить в снимке стабильный идентификатор и обновлять изменившиеся элементы через reconfigureItems.

Навигация, свои view и связка со SwiftUI

Переходы строят на UINavigationController (стек с кнопкой «Назад»), UITabBarController (вкладки) и модальном показе через present. Свой элемент, например карточку товара, делают наследником UIView: подвиды и констрейнты задают в инициализаторе, а в layoutSubviews правят только то, что зависит от итогового размера.

Экран SwiftUI встраивают в UIKit через UIHostingController и показывают как обычный контроллер — в стеке, модально или дочерним внутри старого экрана. Для ячеек с iOS 16 есть UIHostingConfiguration: содержимое описывают на SwiftUI, а список остаётся на UICollectionView. Главная сложность на стыке — данные: если обе стороны держат свою копию состояния, они расходятся, поэтому заводят одну модель-класс.

Утечки памяти и производительность

Объект в Swift живёт, пока на него есть сильная ссылка. Типичная утечка в UIKit: контроллер хранит замыкание — обработчик ответа сети или нажатия, — а замыкание сильно захватывает self. Получается кольцо, и закрытый экран остаётся в памяти со всеми картинками. Лечится списком захвата [weak self] и объявлением делегатов как weak var.

Проверка простая: добавьте в контроллер deinit с выводом в консоль, откройте и закройте экран. Нет строки — контроллер утёк, а Debug Memory Graph в Xcode покажет, кто его держит. Подтормаживающий список проверяют в Instruments, а не на глаз.

Учебный пример: экран списка заказов

Учебная задача: экран загружает заказы с сервера, открывает подробности по нажатию и позволяет отменить заказ. Вы создаёте проект со SceneDelegate и корневым UINavigationController без сториборда. Верстаете ячейку с номером, статусом и суммой и проверяете её на iPhone SE с крупным шрифтом: статус не должен наползать на сумму. Список строите на UICollectionView с diffable data source, где идентификатор — номер заказа, а отмену показываете через reconfigureItems. Подробности пишете на SwiftUI и открываете через UIHostingController. В конце пять раз открываете и закрываете подробности и убеждаетесь в Memory Graph, что лишних экземпляров не осталось.

С чего начать и в каком порядке осваивать

Порядок выстроен от простого к составному: без жизненного цикла непонятно, куда писать вёрстку, без Auto Layout не сверстать ячейку, без ячеек не собрать список, а утечки ищут уже в приложении из нескольких экранов. До начала нужен Swift на уровне опционалов, классов и замыканий, иначе ошибки UIKit трудно отличить от ошибок языка.

  1. Соберите экран кодом и выведите в консоль вызовы методов жизненного цикла.
  2. Сверстайте профиль по макету, поверните устройство, включите крупный шрифт и устраните конфликты констрейнтов.
  3. Сделайте список на UITableView, затем перепишите его на UICollectionView с diffable data source.
  4. Добавьте стек экранов, вкладки и модальное окно.
  5. Встройте экран SwiftUI через UIHostingController.
  6. Пройдитесь по приложению с Memory Graph и исправьте кольца ссылок.

Лучшая проверка — показать код тому, кто пишет на UIKit в продакшене: он быстро заметит забытый weak.

Как выбрать онлайн-курс по UIKit

Отдельных онлайн-курсов только по UIKit почти нет: его изучают внутри программ по iOS-разработке. Поэтому смотрите, сколько проектов сделано на UIKit и проверяет ли кто-то ваш код, а не просто есть ли UIKit в списке технологий.

На курсе «iOS-разработчик» Яндекс Практикума после основ Swift верстают экраны по макетам Figma и делают четыре приложения с ревью кода: квиз с юнит- и UI-тестами, проект с OAuth, многопоточностью и анимациями, трекер на Core Data с MVVM и SwiftUI и командный интернет-магазин. Обучение длится 10 месяцев примерно по 15 часов в неделю, нужен Mac с актуальным Xcode.

У любой школы спросите, на каком SDK собираются учебные проекты: шаблоны, где окно создаётся в AppDelegate без сцен, придётся переделывать под новые требования Apple.

У Нетологии на курсе «iOS-разработчик с нуля» UIKit и SwiftUI изучают вместе с адаптивной вёрсткой и анимацией, а среди инструментов есть Instruments. Программа рассчитана на 11 месяцев по 10–12 часов в неделю, диплом — клиент соцсети с профилем, лентой и картой. Разбивки по модулям на странице нет, так что долю UIKit уточните у школы.

Если удобнее учиться в своём темпе, а не по расписанию вебинаров, сравните программы с наставником и самостоятельными уроками.

Такой формат у Eduson Academy на курсе «iOS-разработчик», тариф «Базовый»: видеоуроки, тренажёры и домашние задания с наставником. Программа начинается с Xcode, Swift и вёрстки в Storyboard, продолжается навигацией, анимацией, работой с памятью и многопоточностью и заканчивается SwiftUI, тестами и публикацией в App Store. UIKit в описании по имени не назван, хотя Storyboard относится к нему, а длительность указана то шесть, то семь месяцев — оба момента уточните у школы.

Перед оплатой попросите пример учебного проекта или ревью: по нему видно, разбирают ли с вами вёрстку и утечки или только принимают работу.

Сравнить онлайн-школы по формату и практике можно в рейтинге онлайн-школ с обучением iOS-разработке. Он составлен по профессии целиком, а не по UIKit, поэтому в каждой программе ищите задачу на совместную работу UIKit и SwiftUI.

Как UIKit влияет на доход

Отдельной статистики зарплат «за UIKit» нет: фреймворк входит в требования к iOS-разработчику наравне со Swift. Общий ориентир — отчёт Хабр Карьеры за первое полугодие 2026 года: медиана разработчиков мобильных приложений — 320 000 рублей в Москве, 299 000 в Санкт-Петербурге и 263 000 в других регионах. Это зарплаты специалистов всех уровней из калькулятора сервиса, а не вилки вакансий, и новичку они не ориентир.

Влияние UIKit косвенное: со SwiftUI можно браться за новые проекты, а с UIKit — ещё и за поддержку крупных приложений. Проверьте это на своём рынке: откройте вакансии junior iOS-разработчика в своём городе и посчитайте, где UIKit стоит среди обязательных требований. Если экран заказов из учебного примера получается без утечек и конфликтов констрейнтов, платная программа нужна скорее ради ревью и командного проекта, чем ради основ.