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

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

Стандартний Bottom Sheet не блокує фон і дозволяє взаємодіяти з основним контентом. Це ключова відмінність від модального Sheet, який вимагає обов'язкової дії для продовження роботи. Використовуйте стандартний Sheet, коли додаткова інформація не критична для основного сценарію.

Модальний Bottom Sheet

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

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

Розширений Bottom Sheet

Розширений 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

Bottom Sheet у 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("Фільтри")
        Button(onClick = onDismiss) { Text("Застосувати") }
    }
}

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("Показати 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"),
                ElevatedButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: Text("Закрити")
                )
            ]
        )
    );
})

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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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