UIKit — это фреймворк для построения графических интерфейсов в iOS и macOS приложениях. Набор включает UIView, UIViewController, элементы управления и систему Auto Layout, позволяя создавать адаптивные и интерактивные экраны. По данным Apple Developer Documentation (2025), UIKit содержит более 200 классов для работы с окнами, вьюхами, анимациями, жестами и текстом — это основа всех приложений под iPhone и iPad.
Главное
UIKit — это фреймворк от Apple, предоставляющий классы для создания и управления пользовательским интерфейсом на iOS, iPadOS и macOS (через Mac Catalyst). Он работает поверх Core Animation, Core Graphics и Quartz Core, абстрагируя низкоуровневую отрисовку в высокоуровневые объекты — кнопки, лейблы, изображения и контейнеры. UIKit появился вместе с iPhone OS 1 в 2007 году и остаётся основным фреймворком для iOS-разработки наряду со SwiftUI.
Фреймворк следует императивному подходу: разработчик создаёт экземпляры классов UIButton, UILabel, UIImageView, задаёт их свойства (цвет, шрифт, положение) и добавляет в иерархию вьюх через addSubview. Каждое изменение интерфейса выполняется явно — никакой магии обновлений за кулисами. Это отличает UIKit от декларативных фреймворков наподобие SwiftUI, где описание состояния автоматически перерисовывает интерфейс.
Фреймворк включает несколько категорий классов. UIView — базовый элемент, от которого наследуются все визуальные компоненты. UIWindow — контейнер верхнего уровня, через который вьюхи отображаются на экране. UIViewController — контроллер, управляющий набором вьюх и реагирующий на повороты экрана, появление клавиатуры и системные уведомления. UIApplication — точка входа, обрабатывающая события касания и нажатия кнопок.
Для текста используются UILabel (статичный текст), UITextField (однострочный ввод), UITextView (многострочный ввод). Для кнопок — UIButton, включая системные, кастомные и с иконографией SF Symbols. Для навигации — UINavigationController, UITabBarController и UISplitViewController. Всего в UIKit более 200 публичных классов.
Архитектура UIKit строится на слоях: каждый слой отвечает за свой аспект отображения. На самом низком уровне находится Core Graphics — движок отрисовки путей, текста и изображений. Выше — Core Animation, управляющая композицией слоёв (CALayer) и анимациями между состояниями. UIKit надстраивает поверх них объектно-ориентированный API: UIView, UIViewController и UIResponder.
Каждое приложение имеет иерархию вьюх (view hierarchy) — дерево, корнем которого выступает UIWindow. Под ним — корневой UIViewController, его вьюха, а внутри — вложенные subviews. События касания распространяются по цепочке responder chain: от самой вложенной вьюхи к родителям и далее к UIApplication. Если ни один объект не обработал касание, оно игнорируется.
Каждый UIView содержит слой CALayer, отвечающий за рендеринг пикселей на экране. Вьюха управляет касаниями и accessibility, слой — графикой: shadow, cornerRadius, border, transform. Разделение позволяет вынести тяжёлую графику на отдельную нить (render server), не блокируя main thread. Apple рекомендует работать с CALayer напрямую, если нужно больше 200 вьюх на экране — это снижает нагрузку на CPU.
Цепочка responder начинается с объекта, который первым получает событие касания. Если он не обрабатывает событие (метод touchesBegan не переопределён), событие передаётся следующему responder в цепочке: next, superview, next responder, UIViewController, UIWindow, UIApplication, App Delegate. Это позволяет перехватывать глобальные жесты и клавиатурные события на уровне сцены, не добавляя обработчик в каждую вьюху.
Каждый UIViewController проходит через строго определённую последовательность событий. Жизненный цикл включает фазы: инициализация, загрузка вьюхи, появление на экране, обновление макета при повороте, скрытие, уход с экрана и освобождение памяти. Разработчик переопределяет соответствующие методы для выполнения своего кода на каждом этапе.
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadUserProfile()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
clearCache()
}
}
В viewDidLoad настраивается интерфейс — создаются сабвьюхи, задаются констрейнты, подписываются делегаты. В viewWillAppear выполняются операции перед показом: загрузка свежих данных из сети, обновление значений. viewDidDisappear — место для отписки от нотификаций и очистки временных данных. Вызов super обязателен во всех переопределениях, иначе цепочка событий нарушится.
В старых версиях iOS существовал метод viewDidUnload, вызываемый при нехватке памяти. Начиная с iOS 6 метод удалён — теперь UIKit автоматически выгружает вьюхи контроллера, когда они не видны. Разработчику достаточно установить все ссылки на вьюхи как weak, чтобы ARC корректно освободил память при получении предупреждения от системы.
UIKit поддерживает два типа переходов: segue (через Storyboard) и программная навигация через UINavigationController. Программный переход выглядит так: navigationController?.pushViewController(detailVC, animated: true). При этом жизненный цикл detailVC проходит в обычном порядке — viewDidLoad вызывается один раз, viewWillAppear — каждый раз при показе.
Auto Layout — это система позиционирования элементов, основанная на математических отношениях (констрейнтах). Вместо жёстко заданных координат X и Y разработчик описывает правила: «кнопка находится справа от лейбла с отступом 16pt» или «вьюха растягивается по ширине экрана с отступами 20pt слева и справа». Система решает получившуюся систему уравнений в runtime, адаптируя интерфейс под любой размер экрана.
Констрейнты можно задать в Interface Builder (через drag-and-drop) или программно на Swift. Каждый констрейнт — это экземпляр класса NSLayoutConstraint с параметрами: firstItem, firstAttribute, relation, secondItem, secondAttribute, multiplier, constant. Активировать констрейнты нужно через isActive = true или массово через NSLayoutConstraint.activate().
С появлением iPhone X (2017) Apple ввела Safe Area — область экрана, свободная от notch, закруглённых углов и индикатора home bar. Констрейнты должны привязываться к view.safeAreaLayoutGuide, а не к view. Layout Margins добавляют внутренние отступы вьюхи, по умолчанию 8pt или 16pt в зависимости от контекста. Использование safeAreaLayoutGuide гарантирует корректное отображение на всех поколениях iPhone и iPad.
Auto Layout поддерживает анимацию через изменение констант констрейнтов. Достаточно обновить constant констрейнта и вызвать UIView.animate с layoutIfNeeded внутри блока анимации. Система плавно пересчитывает положение всех вьюх в иерархии. Этот приём используется для раскрывающихся блоков, адаптивной панели клавиатуры и смены ориентации экрана.
UITableView и UICollectionView — два мощных инструмента UIKit для отображения списков и сеток. UITableView подходит для вертикальных списков с одной колонкой (чат, настройки, лента новостей). UICollectionView — для сеток, горизонтальных списков, каруселей и кастомных раскладок (галерея, продукты, календарь). Оба класса используют паттерн делегирования для разделения данных и внешнего вида.
Источником данных выступает протокол UITableViewDataSource с обязательными методами numberOfRowsInSection и cellForRowAt. Делегат UITableViewDelegate обрабатывает нажатия на ячейки, высоту строк и события скролла. Механизм reuse identifier переиспользует ячейки, ушедшие за край экрана, что критически важно для производительности на больших списках.
class ContactsViewController: UITableViewController {
private let contacts = ["Анна", "Борис", "Виктор"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = contacts[indexPath.row]
cell.contentConfiguration = content
return cell
}
}
Пример показывает минимальный контроллер для отображения массива строк. Ячейка конфигурируется через UIListContentConfiguration — современный API (iOS 14+), заменивший устаревшие textLabel и detailTextLabel. Регистрация класса ячейки в viewDidLoad обязательна, иначе приложение упадёт с исключением в runtime.
Начиная с iOS 13, Apple рекомендует UICollectionViewCompositionalLayout для построения сложных раскладок. Разработчик описывает секцию, группу, элемент и их размеры декларативно — получается сетка с произвольной геометрией: лента, сетка 2x2, карусель, орнамент. Compositional Layout заменил устаревший UICollectionViewFlowLayout для всех новых проектов. В сочетании с DiffableDataSource обновление коллекции сводится к одному вызову apply(snapshot), а анимация изменений выполняется автоматически.
Ниже приведены два практических примера использования UIKit в реальных задачах: создание кастомной вьюхи с тенью и скруглением, а также обработка жеста свайпа для удаления элемента из списка.
extension UIView {
func applyCardStyle() {
layer.cornerRadius = 12
layer.shadowOpacity = 0.15
layer.shadowRadius = 8
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.masksToBounds = false
}
}
@objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
guard let swipedView = gesture.view else { return }
UIView.animate(withDuration: 0.3) {
swipedView.alpha = 0
swipedView.transform = CGAffineTransform(translationX: 300, y: 0)
} completion: { _ in
swipedView.removeFromSuperview()
}
}
Расширение applyCardStyle добавляет тень и скругление любой вьюхе — полезно для карточек продуктов, профилей и уведомлений. Метод handleSwipe с анимацией удаляет элемент, если пользователь провёл по нему вправо. Обработчик добавляется на вьюху через addGestureRecognizer с конфигурацией UISwipeGestureRecognizer(direction: .right). Установка masksToBounds = false важна, чтобы тень не обрезалась границами вьюхи.
Для более сложных интерфейсов используйте UIStackView — контейнер, автоматически распределяющий вложенные вьюхи по горизонтали или вертикали. Stack View упрощает вёрстку: не нужно задавать констрейнты для каждого элемента, достаточно одного констрейнта для самого стека.
Часто задаваемые вопросы
Frame — прямоугольник в координатах superview (позиция + размер). Bounds — прямоугольник в собственных координатах вьюхи (всегда начинается с 0,0). Frame меняется при rotate и scale, bounds — нет.
UIKit автоматически выгружает вьюхи скрытых контроллеров. Разработчику достаточно объявлять свойства вьюх как weak var, чтобы ARC мог освободить память при предупреждении системы.
Для новых проектов Apple рекомендует SwiftUI. Если проект на UIKit — используйте XIB для отдельных экранов или программную вёрстку через SnapKit. Storyboard создаёт merge conflicts и замедляет сборку.
Используйте UIColor с поддержкой traitCollection: UIColor { $0.userInterfaceStyle == .dark ? ... : ... }. Активируйте Dark Mode в Info.plist ключом UIUserInterfaceStyle.
UIStackView автоматически рассчитывает позиции и размеры вложенных вьюх на основе alignment, distribution и spacing. Это сокращает код констрейнтов на 60–80% и упрощает адаптацию под разные экраны.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также