Sheet в мобильной разработке — суть, виды и как работают

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

Sheet — это UI-компонент, который появляется в нижней части экрана поверх основного контента и предоставляет дополнительные действия или информацию. Bottom Sheet — наиболее распространённый вид, определённый в гайдлайнах Material Design 3 (Google, 2024). В отличие от диалоговых окон, Sheet не блокирует полностью взаимодействие с фоном и поддерживает состояния collapsed и expanded. Понимание типов и поведения Sheet необходимо для построения удобной навигации в мобильных приложениях.

Главное

  • Sheet — это UI-компонент, появляющийся снизу экрана поверх основного контента
  • Bottom Sheet бывает стандартным (немодальным) и модальным — для обязательных действий
  • Material Design 3 определяет два состояния: collapsed и expanded с перетаскиванием
  • На iOS Sheet реализуется через UISheetPresentationController в UIKit и .sheet в SwiftUI
  • В Flutter Bottom Sheet создаётся через showBottomSheet и showModalBottomSheet

Что такое Sheet в мобильных приложениях

Sheet — это поверхностный UI-компонент, который выезжает снизу экрана и отображает дополнительный контент или действия, не уводя пользователя с текущего экрана. В отличие от полноэкранных переходов, Sheet сохраняет контекст: пользователь видит фоновый экран и понимает, откуда появился Sheet.

Архитектура Sheet основана на контейнере с изменяемой высотой. В минимальном состоянии (collapsed) видна только часть контента — обычно заголовок или небольшая панель. Пользователь может потянуть Sheet вверх, чтобы развернуть его (expanded), или смахнуть вниз, чтобы закрыть. Такое поведение напоминает физический лист бумаги, который выдвигают из-под стопки — отсюда и название.

Google в гайдлайнах Material Design 3 (2024) выделяет два ключевых сценария использования Sheet: отображение дополнительных действий, которые не поместились на основной панели инструментов, и показ форм или детальной информации без перехода на отдельный экран. На iOS Apple добавила системную поддержку Sheet начиная с iOS 15 через UISheetPresentationController, что подтверждает универсальность паттерна.

Типы Bottom Sheet: стандартный, модальный и расширенный

Material Design определяет три типа Bottom Sheet, каждый со своим поведением и областью применения. Выбор правильного типа напрямую влияет на пользовательский опыт и соответствие гайдлайнам платформы.

Стандартный Bottom Sheet (Standard)

Стандартный Bottom Sheet — немодальный компонент: пользователь может взаимодействовать с фоновым экраном, не закрывая Sheet. Например, листая список товаров в фоновом окне, пользователь видит фильтры в Bottom Sheet и может изменять их без закрытия панели. Sheet подстраивает свою высоту под контент — от 30% до 90% экрана.

Стандартный Bottom Sheet не блокирует фон и позволяет взаимодействовать с основным контентом. Это ключевое отличие от модального Sheet, который требует обязательного действия для продолжения работы. Используйте стандартный Sheet, когда дополнительная информация не критична для основного сценария.

Модальный Bottom Sheet (Modal)

Модальный Bottom Sheet блокирует взаимодействие с фоновым экраном, пока пользователь не выполнит действие внутри Sheet. Такой Sheet всегда показывается в expanded-состоянии и требует явного закрытия — через кнопку, действие или свайп вниз. Material Design рекомендует модальный Sheet для форм входа, подтверждений и критичных настроек.

На Android модальный Bottom Sheet реализуется через BottomSheetDialogFragment, который автоматически блокирует фон. На iOS аналогичное поведение обеспечивает модальный вариант UISheetPresentationController с параметром .mediumDetent. Модальный Sheet следует использовать только тогда, когда контекст требует внимания пользователя.

Расширенный Bottom Sheet (Expanding)

Расширенный Bottom Sheet комбинирует свойства стандартного и модального: он начинается как немодальный в collapsed-состоянии, но при перетаскивании вверх становится модальным. На практике это означает, что пользователь может сначала мельком взглянуть на содержимое, а затем принять решение — развернуть Sheet для детального изучения или закрыть.

Этот паттерн особенно популярен в картах и навигаторах, где нижняя панель показывает краткую информацию о точке маршрута, а при свайпе вверх раскрывается с деталями. Google Maps использует именно такой расширенный Sheet для отображения информации о местах и маршрутах.

Тип SheetБлокировка фонаНачальное состояниеПример
СтандартныйНетCollapsedФильтры в каталоге
МодальныйДаExpandedФорма входа
РасширенныйЧастичноCollapsedКарточка места

Bottom Sheet на Android: Material Design и Jetpack Compose

Android SDK предоставляет несколько API для реализации Bottom Sheet, начиная от классического View-подхода и заканчивая современным Jetpack Compose. Material Components Library для Android включает готовые реализации BottomSheetDialogFragment и BottomSheetBehavior.

BottomSheetBehavior в XML-разметке

BottomSheetBehavior — это класс из Material Components, который прикрепляется к любой View и управляет её положением на экране. Разработчик задаёт три состояния: STATE_COLLAPSED (свёрнуто), STATE_EXPANDED (развёрнуто) и STATE_HIDDEN (скрыто). Behavior автоматически обрабатывает жесты перетаскивания и анимацию.

kotlin
val sheet = findViewById<View>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(sheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.peekHeight = 200

BottomSheet в Jetpack Compose

Jetpack Compose предоставляет более декларативный API через компонент ModalBottomSheet из Material 3. В отличие от View-подхода, в Compose Bottom Sheet является composable-функцией, принимающей состояние и контент. Sheet автоматически анимирует появление, скрытие и изменение высоты при перетаскивании.

kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterSheet(onDismiss: () -> Unit) {
    ModalBottomSheet(onDismissRequest = onDismiss) {
        Text("Filters")
        Button(onClick = onDismiss) { Text("Apply") }
    }
}

BottomSheetDialogFragment для модальных сценариев

BottomSheetDialogFragment — это специализированный DialogFragment, который отображается как Bottom Sheet. Он автоматически обрабатывает модальность, жизненный цикл и конфигурационные изменения. Разработчику нужно только переопределить onCreateView и вернуть layout Sheet. По данным документации Google (Android Developers, 2024), BottomSheetDialogFragment — рекомендуемый способ для модальных Bottom Sheet в классическом Android.

Sheet на iOS: UISheetPresentationController и SwiftUI

Apple ввела системную поддержку Sheet начиная с iOS 15 через UISheetPresentationController. До этого разработчики реализовывали Bottom Sheet вручную через custom transition или сторонние библиотеки. Нативный Sheet от Apple поддерживает detents — предопределённые уровни раскрытия.

UISheetPresentationController в UIKit

UISheetPresentationController — это встроенный контроллер презентации, который отображает View Controller как Sheet. Разработчик задаёт массив detents — значений высоты, на которых Sheet может остановиться. iOS 16 добавила custom detents с произвольной высотой. Apple рекомендует использовать medium (.medium) и large (.large) detents как основные.

swift
let viewController = MySheetViewController()
if let sheet = viewController.sheetPresentationController {
    sheet.detents = [.medium, .large]
    sheet.prefersGrabberVisible = true
    sheet.preferredCornerRadius = 16
}
present(viewController, animated: true)

.sheet модификатор в SwiftUI

SwiftUI предоставляет модификатор .sheet, который привязывает отображение Sheet к состоянию. Когда published-переменная становится true, SwiftUI автоматически показывает Sheet. SwiftUI также поддерживает detents через модификатор .presentationDetents, добавленный в iOS 16.

swift
struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        Button("Show Sheet") { showSheet = true }
            .sheet(isPresented: $showSheet) {
                FilterView()
                    .presentationDetents([.medium, .large])
            }
    }
}

Sheet в кросс-платформенных фреймворках: Flutter и React Native

Кросс-платформенные фреймворки также поддерживают Bottom Sheet, адаптируя поведение под целевую платформу. Flutter и React Native предоставляют встроенные и кастомные реализации с разной степенью гибкости.

Bottom Sheet в Flutter

Flutter SDK содержит два метода для отображения Bottom Sheet: showBottomSheet (стандартный) и showModalBottomSheet (модальный). Material Design во Flutter следует тем же принципам, что и в Android — Sheet появляется снизу, поддерживает перетаскивание и настраиваемую высоту. Для расширенного поведения с детектами используется DraggableScrollableSheet.

dart
Scaffold.of(context).showBottomSheet((context) {
    return Container(
        padding: EdgeInsets.all(16),
        child: Column(
            children: [
                Text("Sheet Content"),
                ElevatedButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: Text("Close")
                )
            ]
        )
    );
})

Bottom Sheet в React Native

React Native не имеет встроенного Bottom Sheet компонента в ядре, поэтому разработчики используют сторонние библиотеки. Наиболее популярная — @gorhom/bottom-sheet (более 7 тысяч звёзд на GitHub, 2024). Она предоставляет gesture-driven Bottom Sheet с поддержкой snap points, анимаций и закреплённых заголовков. Библиотека написана на Reanimated 2 и Gesture Handler для производительности на 60 FPS.

Лучшие практики и типичные ошибки

Правильное использование Bottom Sheet требует соблюдения гайдлайнов платформы и понимания сценариев, в которых Sheet уместен. Рассмотрим ключевые рекомендации и распространённые ошибки при проектировании Sheet.

Когда использовать Bottom Sheet

Bottom Sheet оптимален для действий, которые являются дополнительными по отношению к основному контенту на экране. Фильтры, сортировка, выбор опций, краткая информация о элементе — типичные сценарии. Material Design рекомендует использовать Bottom Sheet для инструментов, которые не должны занимать весь экран, но требуют больше места, чем Action Sheet или Popup Menu.

Когда НЕ использовать Bottom Sheet

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

Ошибка: слишком высокий collapsed-режим

Типичная ошибка — установка peekHeight (высота в свёрнутом состоянии) более 40% экрана. Пользователь не понимает, видит ли он Sheet целиком или его можно развернуть. Material Design рекомендует peekHeight в пределах 15-30% высоты экрана, чтобы оставить заметную часть контента скрытой и мотивировать на перетаскивание.

Ошибка: игнорирование свайп-жеста на iOS

На iOS пользователи ожидают, что Sheet можно закрыть свайпом вниз из любого положения. Если вы отключаете этот жест (через UISheetPresentationController.prefersEdgeAttachedInCompactHeight), пользователь испытывает фрустрацию, пытаясь закрыть Sheet привычным способом. Apple Human Interface Guidelines (2024) подчёркивают, что свайп для закрытия — базовое ожидание пользователя iOS.

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

В чём разница между Bottom Sheet и диалоговым окном?

Bottom Sheet не блокирует фон полностью и поддерживает перетаскивание, а диалоговое окно модально и требует обязательного действия. Bottom Sheet лучше подходит для дополнительных опций, диалог — для критичных подтверждений.

Можно ли использовать Bottom Sheet вместе с клавиатурой?

Да, но требуется настройка adjustResize или adjustPan в манифесте Android. На iOS клавиатура автоматически поднимает Sheet. Flutter и React Native требуют ручной обработки через MediaQuery для корректного позиционирования.

Сколько элементов оптимально размещать в Bottom Sheet?

Рекомендуется не более 5-7 элементов в стандартном Sheet. Если контента больше — используйте скролл или разбивку на категории. Material Design советует не превышать 90% высоты экрана в expanded-состоянии.

Как обработать закрытие Sheet при нажатии на фон?

Для модального Sheet установите setCancelable(true) на Android или isModalInPresentation = false на iOS. В Jetpack Compose onDismissRequest автоматически обрабатывает тап по фону. В SwiftUI свайп вниз — стандартное поведение.

Поддерживает ли Bottom Sheet accessibility?

Да, все нативные реализации поддерживают VoiceOver и TalkBack. Убедитесь, что FocusManager корректно перемещает фокус в Sheet при его открытии и возвращает обратно при закрытии. Кастомные реализации требуют ручной настройки accessibility.

Итоги

  • Sheet — UI-компонент, выезжающий снизу экрана для дополнительного контента без перехода на новый экран
  • Три типа Sheet: стандартный (немодальный), модальный (с блокировкой фона) и расширенный (комбинированный)
  • Material Design 3 определяет Bottom Sheet с состояниями collapsed и expanded и поддержкой перетаскивания
  • На Android реализуется через BottomSheetBehavior, BottomSheetDialogFragment и ModalBottomSheet в Compose
  • На iOS используется UISheetPresentationController с detents с iOS 15 и .sheet модификатор в SwiftUI
  • В кросс-платформенных фреймворках Bottom Sheet доступен через showBottomSheet (Flutter) и @gorhom/bottom-sheet (React Native)
  • Избегайте Sheet для критичных предупреждений и форм с большим количеством полей — используйте отдельные экраны

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

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

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

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