Full Screen Cover — стиль модальной презентации в iOS, при котором новый экран занимает весь дисплей без видимости родительского контента. В отличие от Page Sheet, Full Screen Cover полностью скрывает предыдущий экран и используется для медиаконтента, фоторедакторов и экранов авторизации. По данным Apple Developer, 2025, этот стиль был дефолтным до iOS 13, но остаётся предпочтительным для immersive-сценариев. В SwiftUI модификатор .fullScreenCover предоставляет декларативный API для полноэкранной презентации.
Главное
Full Screen Cover — это стиль модальной презентации в iOS, при котором представляемый контроллер занимает весь экран устройства. Родительский контент полностью скрывается, что создаёт эффект погружения и фокусирует пользователя на текущей задаче.
До iOS 13 Full Screen Cover был единственным стилем модальной презентации на iPhone. Все вызовы present(_:animated:completion:) по умолчанию использовали .fullScreen. Начиная с iOS 13, Apple изменила дефолтный стиль на .automatic, который для iPhone выбирает .pageSheet. Однако Full Screen Cover остаётся доступным и применяется для сценариев, где важна полная фокусировка.
В отличие от Page Sheet, Full Screen Cover не позволяет взаимодействовать с родительским контентом и не показывает его под модальным окном. Пользователь не может закрыть Full Screen Cover свайпом вниз — для закрытия требуется программный вызов dismiss(animated:completion:) или кнопка закрытия на самом экране. Это поведение важно учитывать при проектировании UX.
Page Sheet — второй основной стиль модальной презентации, появившийся в iOS 13. Page Sheet отображается карточкой с отступом сверху, под которой виден родительский экран. Пользователь может закрыть Page Sheet свайпом вниз. Full Screen Cover, напротив, скрывает родительский контент и не поддерживает свайп-закрытие.
| Характеристика | Full Screen Cover | Page Sheet |
|---|---|---|
| Перекрытие фона | Полное, родительский контент не виден | Частичное, родитель виден под карточкой |
| Закрытие свайпом | Нет, только программно или через кнопку | Да, свайп вниз закрывает |
| Типичное применение | Видео, камера, фоторедактор, PDF | Формы, настройки, детальный просмотр |
| Анимация показа | Снизу вверх, полный экран | Снизу вверх, карточка с отступом |
| Доступность | iOS 2+ | iOS 13+ |
Выбор между Full Screen Cover и Page Sheet зависит от контента и контекста. Рекомендуется использовать Full Screen Cover для контента, который требует полного внимания: видео в полноэкранном режиме, предпросмотр фотографий, сканирование документов. Page Sheet — для задач, где контекст родительского экрана важен: формы редактирования, выбор опций, просмотр деталей.
UIKit предоставляет константу UIModalPresentationStyle.fullScreen для настройки стиля модальной презентации. Установка этого свойства на UIViewController перед вызовом present гарантирует, что контроллер отобразится во весь экран. Контроллер также управляет поведением при появлении клавиатуры и обработкой системных событий.
После установки стиля .fullScreen рекомендуется настроить presentationController?.delegate для обработки событий закрытия. Делегат UIAdaptivePresentationControllerDelegate позволяет перехватить попытку закрытия и предотвратить потерю данных. В отличие от Page Sheet, для Full Screen Cover делегат срабатывает только при программном вызове dismiss.
Full Screen Cover корректно обрабатывает поворот экрана и появление клавиатуры. При повороте модальный контроллер автоматически адаптируется под новую ориентацию. UIKeyboardWillShowNotification позволяет сдвинуть контент вверх при появлении клавиатуры, чтобы текстовые поля оставались видимыми. В отличие от Page Sheet, Full Screen Cover не меняет своих размеров при появлении клавиатуры.
let playerVC = VideoPlayerViewController()
playerVC.modalPresentationStyle = .fullScreen
playerVC.modalTransitionStyle = .crossDissolve
present(playerVC, animated: true) {
playerVC.startPlayback()
}
// Dismiss
dismiss(animated: true) {
print("Player dismissed")
}
SwiftUI предоставляет модификатор .fullScreenCover для декларативного создания полноэкранных модальных окон. В отличие от .sheet (Page Sheet), .fullScreenCover создаёт стиль .fullScreen с аналогичным поведением: полное перекрытие контента и отсутствие свайп-закрытия.
Модификатор принимает binding на Bool или опциональный идентифицируемый объект. При установке binding в true SwiftUI анимирует появление полноэкранного окна. Для передачи данных используется параметр onDismiss и замыкание с контентом. Environment-значение \.dismiss позволяет закрыть модальное окно изнутри.
Выбор между .fullScreenCover и .sheet в SwiftUI аналогичен UIKit: .fullScreenCover для immersive-контента, .sheet для карточек. SwiftUI автоматически выбирает правильное поведение закрытия: .sheet можно закрыть свайпом, .fullScreenCover — только программно. Модификаторы можно комбинировать в одной иерархии View.
struct CameraView: View {
@State private var showCamera = false
var body: some View {
Button("Open Camera") {
showCamera = true
}
.fullScreenCover(isPresented: $showCamera) {
CameraPreviewView()
.ignoresSafeArea()
}
}
}
struct CameraPreviewView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
VStack {
Spacer()
Button("Capture") { dismiss() }
.foregroundColor(.white)
}
}
}
}
Full Screen Cover поддерживает кастомные анимации через UIModalTransitionStyle в UIKit и кастомные переходы в SwiftUI. Стандартные стили: .coverVertical (снизу вверх), .crossDissolve (плавное появление), .flipHorizontal (переворот) и .partialCurl (эффект страницы).
Для полностью кастомной анимации реализуйте протокол UIViewControllerAnimatedTransitioning. Он позволяет определить длительность анимации и сам переход через метод animateTransition(using:). Контроллер анимации назначается через делегат UINavigationControllerDelegate или UIViewControllerTransitioningDelegate.
В SwiftUI кастомные переходы для .fullScreenCover создаются через matchedGeometryEffect. Этот модификатор анимирует перемещение элемента из родительского View в полноэкранное окно. Например, при нажатии на миниатюру фото она плавно разворачивается на весь экран, создавая эффект непрерывности. MatchedGeometryEffect работает с id и namespace, связывающими элемент в исходной и целевой позиции.
struct PhotoViewer: View {
@State private var selectedPhoto: String?
@Namespace private var animation
var body: some View {
HStack {
ForEach(["photo1", "photo2"], id: \.self) { photo in
Image(photo)
.matchedGeometryEffect(id: photo, in: animation)
.onTapGesture { selectedPhoto = photo }
}
}
.fullScreenCover(item: $selectedPhoto) { photo in
Image(photo)
.matchedGeometryEffect(id: photo, in: animation)
.ignoresSafeArea()
}
}
}
Full Screen Cover рекомендуется для сценариев, где контент должен занимать весь экран без отвлечения на родительский интерфейс. Apple HIG выделяет три основные категории: медиаконтент, инструменты создания контента и временные системные интерфейсы.
Видеоплееры, просмотр фотографий, чтение PDF и комиксов — типичные примеры использования Full Screen Cover. AVPlayerViewController в iOS автоматически использует полноэкранный режим при переходе в landscape. Фоторедакторы вроде Adobe Lightroom открывают полноэкранный редактор поверх библиотеки снимков.
Камера, сканер документов, запись голоса — задачи, требующие полного внимания пользователя. UIImagePickerController до iOS 14 использовал Full Screen Cover для камеры. Начиная с iOS 14, системный пикер использует Page Sheet, но разработчик может принудительно установить .fullScreen для кастомной камеры.
Не используйте Full Screen Cover для: форм регистрации (предпочтителен Page Sheet), экранов с текстовым вводом, где важен контекст родительской страницы, и последовательной навигации внутри модального окна. Material Design также рекомендует избегать блокировки системной кнопки назад — в iOS это допустимо, но пользователь должен иметь явный способ закрытия через UI-элемент.
Часто задаваемые вопросы
.fullScreen скрывает родительский контроллер и удаляет его из иерархии отображения. .overFullScreen показывает модальный контроллер поверх родительского, но родитель остаётся в иерархии и продолжает получать события. overFullScreen полезен для прозрачных фонов и кастомных анимаций слоёв.
Apple изменила дефолтный стиль в iOS 13 для улучшения взаимодействия с пользователем. Page Sheet позволяет видеть контекст родительского экрана и закрывать модальное окно свайпом, что ускоряет навигацию. Full Screen Cover остаётся для сценариев, где требуется полная фокусировка без отвлечения на фон.
В UIKit вызовите dismiss(animated:completion:) на presentingViewController или presentedViewController. В SwiftUI используйте Environment-значение \.dismiss и вызовите его как функцию. Для программного закрытия из родительского контроллера измените binding, переданное в .fullScreenCover, на false.
Да, Full Screen Cover работает на iPad. Для iPad доступны дополнительные стили: .formSheet (центрированное окно фиксированного размера) и .currentContext (относительно родительского контроллера). На iPad Full Screen Cover может выглядеть как Page Sheet, если не установлен modalPresentationStyle принудительно.
В отличие от Page Sheet, Full Screen Cover не закрывается свайпом, поэтому потеря данных возможна только при программном dismiss. Переопределите метод dismiss(animated:completion:) или используйте UIAdaptivePresentationControllerDelegate, который вызывается перед закрытием. Покажите UIAlertController с вариантами: сохранить, отменить или остаться на экране.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также