Sheet w rozwoju mobilnym — istota, rodzaje i działanie

Autor: IT Sectr Opublikowano: 2026-06-10 Czas czytania: 10 min

Sheet — to komponent UI, który pojawia się w dolnej części ekranu nad główną treścią i udostępnia dodatkowe akcje lub informacje. Bottom Sheet to najczęściej spotykany typ, zdefiniowany w wytycznych Material Design 3 (Google, 2024). W przeciwieństwie do okien dialogowych, Sheet nie blokuje całkowicie interakcji z tłem i obsługuje stany collapsed i expanded. Zrozumienie typów i zachowania Sheet jest niezbędne do budowania wygodnej nawigacji w aplikacjach mobilnych.

Najważniejsze

  • Sheet — to komponent UI pojawiający się na dole ekranu nad główną treścią
  • Bottom Sheet występuje w wersji standardowej (niemodalnej) i modalnej — dla obowiązkowych działań
  • Material Design 3 definiuje dwa stany: collapsed i expanded z przeciąganiem
  • Na iOS Sheet jest implementowany przez UISheetPresentationController w UIKit i .sheet w SwiftUI
  • We Flutter Bottom Sheet jest tworzony przez showBottomSheet i showModalBottomSheet

Czym jest Sheet w aplikacjach mobilnych

Sheet — to powierzchniowy komponent UI, który wysuwa się z dołu ekranu i wyświetla dodatkową treść lub akcje, nie przenosząc użytkownika z bieżącego ekranu. W przeciwieństwie do przejść pełnoekranowych, Sheet zachowuje kontekst: użytkownik widzi ekran tła i rozumie, skąd pojawił się Sheet.

Architektura Sheet opiera się na kontenerze o zmiennej wysokości. W minimalnym stanie (collapsed) widoczna jest tylko część treści — zazwyczaj nagłówek lub mały panel. Użytkownik może przeciągnąć Sheet w górę, aby go rozwinąć (expanded), lub przesunąć w dół, aby go zamknąć. Takie zachowanie przypomina fizyczną kartkę papieru wysuwaną spod stosu — stąd nazwa.

Google w wytycznych Material Design 3 (2024) wyróżnia dwa kluczowe scenariusze użycia Sheet: wyświetlanie dodatkowych akcji, które nie zmieściły się na głównym pasku narzędzi, oraz pokazywanie formularzy lub szczegółowych informacji bez przechodzenia do osobnego ekranu. Na iOS Apple dodało systemową obsługę Sheet od iOS 15 przez UISheetPresentationController, co potwierdza uniwersalność tego wzorca.

Rodzaje Bottom Sheet: standardowy, modalny i rozszerzony

Material Design definiuje trzy typy Bottom Sheet, każdy z własnym zachowaniem i obszarem zastosowania. Wybór odpowiedniego typu bezpośrednio wpływa na doświadczenie użytkownika i zgodność z wytycznymi platformy.

Standardowy Bottom Sheet

Standardowy Bottom Sheet — komponent niemodalny: użytkownik może wchodzić w interakcję z ekranem tła bez zamykania Sheet. Na przykład, przeglądając listę produktów w oknie tła, użytkownik widzi filtry w Bottom Sheet i może je zmieniać bez zamykania panelu. Sheet dostosowuje swoją wysokość do treści — od 30% do 90% ekranu.

Standardowy Bottom Sheet nie blokuje tła i pozwala na interakcję z główną treścią. To kluczowa różnica w porównaniu z modalnym Sheet, który wymaga obowiązkowego działania, aby kontynuować pracę. Używaj standardowego Sheet, gdy dodatkowa informacja nie jest krytyczna dla głównego scenariusza.

Modalny Bottom Sheet

Modalny Bottom Sheet blokuje interakcję z ekranem tła, dopóki użytkownik nie wykona akcji wewnątrz Sheet. Taki Sheet jest zawsze wyświetlany w stanie expanded i wymaga jawnego zamknięcia — przez przycisk, akcję lub przesunięcie w dół. Material Design zaleca modalny Sheet dla formularzy logowania, potwierdzeń i krytycznych ustawień.

Na Androidzie modalny Bottom Sheet jest implementowany przez BottomSheetDialogFragment, który automatycznie blokuje tło. Na iOS analogiczne zachowanie zapewnia modalna wersja UISheetPresentationController z parametrem .mediumDetent. Modalnego Sheet należy używać tylko wtedy, gdy kontekst wymaga uwagi użytkownika.

Rozszerzony Bottom Sheet

Rozszerzony Bottom Sheet łączy właściwości standardowego i modalnego: zaczyna się jako niemodalny w stanie collapsed, ale przy przeciągnięciu w górę staje się modalny. W praktyce oznacza to, że użytkownik może najpierw rzucić okiem na zawartość, a następnie podjąć decyzję — rozwinąć Sheet w celu szczegółowego zapoznania się lub zamknąć.

Ten wzorzec jest szczególnie popularny w mapach i nawigacjach, gdzie dolny panel pokazuje krótką informację o punkcie trasy, a przy przesunięciu w górę rozwija się ze szczegółami. Google Maps używa właśnie takiego rozszerzonego Sheet do wyświetlania informacji o miejscach i trasach.

Typ SheetBlokada tłaStan początkowyPrzykład
StandardowyNieCollapsedFiltry w katalogu
ModalnyTakExpandedFormularz logowania
RozszerzonyCzęściowoCollapsedKarta miejsca

Bottom Sheet na Androidzie: Material Design i Jetpack Compose

Android SDK udostępnia kilka API do implementacji Bottom Sheet, począwszy od klasycznego podejścia View, a skończywszy na nowoczesnym Jetpack Compose. Material Components Library dla Androida zawiera gotowe implementacje BottomSheetDialogFragment i BottomSheetBehavior.

BottomSheetBehavior w układzie XML

BottomSheetBehavior — to klasa z Material Components, która dołącza się do dowolnego View i zarządza jego pozycją na ekranie. Deweloper ustawia trzy stany: STATE_COLLAPSED (zwinięty), STATE_EXPANDED (rozwinięty) i STATE_HIDDEN (ukryty). Behavior automatycznie obsługuje gesty przeciągania i animację.

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

Bottom Sheet w Jetpack Compose

Jetpack Compose udostępnia bardziej deklaratywne API przez komponent ModalBottomSheet z Material 3. W przeciwieństwie do podejścia View, w Compose Bottom Sheet jest funkcją composable, która przyjmuje stan i treść. Sheet automatycznie animuje pojawianie się, ukrywanie i zmianę wysokości przy przeciąganiu.

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

BottomSheetDialogFragment dla scenariuszy modalnych

BottomSheetDialogFragment — to wyspecjalizowany DialogFragment, który wyświetla się jako Bottom Sheet. Automatycznie obsługuje modalność, cykl życia i zmiany konfiguracji. Deweloper musi tylko nadpisać onCreateView i zwrócić układ Sheet. Według dokumentacji Google (Android Developers, 2024), BottomSheetDialogFragment to zalecany sposób dla modalnych Bottom Sheet w klasycznym Androidzie.

Sheet na iOS: UISheetPresentationController i SwiftUI

Apple wprowadziła systemową obsługę Sheet od iOS 15 przez UISheetPresentationController. Wcześniej deweloperzy implementowali Bottom Sheet ręcznie przez custom transition lub biblioteki zewnętrzne. Natywny Sheet od Apple obsługuje detents — predefiniowane poziomy rozwinięcia.

UISheetPresentationController w UIKit

UISheetPresentationController — to wbudowany kontroler prezentacji, który wyświetla View Controller jako Sheet. Deweloper ustawia tablicę detents — wartości wysokości, na których Sheet może się zatrzymać. iOS 16 dodał custom detents z dowolną wysokością. Apple zaleca używanie medium (.medium) i large (.large) detents jako podstawowych.

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

Modyfikator .sheet w SwiftUI

SwiftUI udostępnia modyfikator .sheet, który wiąże wyświetlanie Sheet ze stanem. Gdy opublikowana zmienna (published) staje się true, SwiftUI automatycznie pokazuje Sheet. SwiftUI obsługuje również detents przez modyfikator .presentationDetents, dodany w iOS 16.

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

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

Sheet w frameworkach cross-platformowych: Flutter i React Native

Frameworki cross-platformowe również obsługują Bottom Sheet, dostosowując zachowanie do platformy docelowej. Flutter i React Native udostępniają wbudowane i niestandardowe implementacje z różnym stopniem elastyczności.

Bottom Sheet we Flutter

Flutter SDK zawiera dwie metody wyświetlania Bottom Sheet: showBottomSheet (standardowy) i showModalBottomSheet (modalny). Material Design we Flutter kieruje się tymi samymi zasadami co na Androidzie — Sheet pojawia się na dole, obsługuje przeciąganie i konfigurowalną wysokość. Dla rozszerzonego zachowania z detektami używany jest DraggableScrollableSheet.

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

Bottom Sheet w React Native

React Native nie ma wbudowanego komponentu Bottom Sheet w rdzeniu, dlatego deweloperzy używają bibliotek zewnętrznych. Najbardziej popularna — @gorhom/bottom-sheet (ponad 7 tysięcy gwiazdek na GitHubie, 2024). Udostępnia ona gesture-driven Bottom Sheet z obsługą snap points, animacji i przypiętych nagłówków. Biblioteka jest napisana w Reanimated 2 i Gesture Handler dla wydajności na poziomie 60 FPS.

Najlepsze praktyki i typowe błędy

Prawidłowe użycie Bottom Sheet wymaga przestrzegania wytycznych platformy i zrozumienia scenariuszy, w których Sheet jest odpowiedni. Omówmy kluczowe zalecenia i typowe błędy przy projektowaniu Sheet.

Kiedy używać Bottom Sheet

Bottom Sheet jest optymalny dla działań, które są dodatkowe w stosunku do głównej treści na ekranie. Filtry, sortowanie, wybór opcji, krótka informacja o elemencie — typowe scenariusze. Material Design zaleca używanie Bottom Sheet dla narzędzi, które nie powinny zajmować całego ekranu, ale wymagają więcej miejsca niż Action Sheet lub Popup Menu.

Kiedy NIE używać Bottom Sheet

Nie używaj Bottom Sheet dla krytycznych ostrzeżeń lub błędów — do tego służą okna dialogowe. Unikaj Sheet z dużą liczbą pól wprowadzania, które wymagają przewijania: użytkownik ma trudności z dostępem do klawiatury i traci kontekst. Jeśli Sheet zawiera więcej niż siedem elementów akcji, rozważ osobny ekran zamiast Sheet.

Błąd: zbyt wysoki tryb collapsed

Typowym błędem jest ustawienie peekHeight (wysokość w stanie zwiniętym) na ponad 40% ekranu. Użytkownik nie rozumie, czy widzi Sheet w całości, czy można go rozwinąć. Material Design zaleca peekHeight w zakresie 15–30% wysokości ekranu, aby pozostawić zauważalną część treści ukrytą i motywować do przeciągania.

Błąd: ignorowanie gestu przesunięcia na iOS

Na iOS użytkownicy oczekują, że Sheet można zamknąć, przesuwając go w dół z dowolnej pozycji. Jeśli wyłączysz ten gest (przez UISheetPresentationController.prefersEdgeAttachedInCompactHeight), użytkownik będzie sfrustrowany, próbując zamknąć Sheet w znajomy sposób. Apple Human Interface Guidelines (2024) podkreślają, że przesunięcie w celu zamknięcia to podstawowe oczekiwanie użytkownika iOS.

Często zadawane pytania

Jaka jest różnica między Bottom Sheet a oknem dialogowym?

Bottom Sheet nie blokuje całkowicie tła i obsługuje przeciąganie, a okno dialogowe jest modalne i wymaga obowiązkowego działania. Bottom Sheet lepiej nadaje się do dodatkowych opcji, okno dialogowe — do krytycznych potwierdzeń.

Czy można używać Bottom Sheet razem z klawiaturą?

Tak, ale wymaga ustawienia adjustResize lub adjustPan w manifeście Androida. Na iOS klawiatura automatycznie podnosi Sheet. Flutter i React Native wymagają ręcznej obsługi przez MediaQuery do prawidłowego pozycjonowania.

Ile elementów optymalnie umieścić w Bottom Sheet?

Zaleca się nie więcej niż 5–7 elementów w standardowym Sheet. Jeśli treści jest więcej — użyj przewijania lub podziału na kategorie. Material Design radzi nie przekraczać 90% wysokości ekranu w stanie expanded.

Jak obsłużyć zamknięcie Sheet po kliknięciu w tło?

Dla modalnego Sheet ustaw setCancelable(true) na Androidzie lub isModalInPresentation = false na iOS. W Jetpack Compose onDismissRequest automatycznie obsługuje tapnięcie w tło. W SwiftUI przesunięcie w dół to standardowe zachowanie.

Czy Bottom Sheet obsługuje accessibility?

Tak, wszystkie natywne implementacje obsługują VoiceOver i TalkBack. Upewnij się, że FocusManager prawidłowo przenosi fokus do Sheet przy jego otwieraniu i zwraca go z powrotem przy zamykaniu. Niestandardowe implementacje wymagają ręcznej konfiguracji accessibility.

Podsumowanie

  • Sheet — komponent UI wysuwający się z dołu ekranu dla dodatkowej treści bez przechodzenia na nowy ekran
  • Trzy typy Sheet: standardowy (niemodalny), modalny (z blokadą tła) i rozszerzony (kombinowany)
  • Material Design 3 definiuje Bottom Sheet ze stanami collapsed i expanded oraz obsługą przeciągania
  • Na Androidzie implementowany przez BottomSheetBehavior, BottomSheetDialogFragment i ModalBottomSheet w Compose
  • Na iOS używany jest UISheetPresentationController z detents od iOS 15 i modyfikator .sheet w SwiftUI
  • W frameworkach cross-platformowych Bottom Sheet jest dostępny przez showBottomSheet (Flutter) i @gorhom/bottom-sheet (React Native)
  • Unikaj Sheet dla krytycznych ostrzeżeń i formularzy z dużą liczbą pól — używaj osobnych ekranów

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również