Modal Presentation w rozwoju mobilnym: co to jest, rodzaje ekranów

Autor: IT Sectr Opublikowano: 2026-06-09 Czas czytania: 5 min

Modal Presentation — sposób wyświetlania ekranu ponad bieżącym kontekstem z blokadą interakcji z poprzednim interfejsem. W tworzeniu aplikacji mobilnych okna modalne są używane do zadań wymagających skupienia: wprowadzanie danych, potwierdzanie działań, autoryzacja i wybór opcji. Według Apple HIG, 2025, prezentacje modalne powinny zajmować nie więcej niż 20% scenariuszy nawigacyjnych w aplikacji. W Android modalność jest realizowana przez DialogFragment, BottomSheet i Activity z określonymi flagami launch.

Najważniejsze

  • Modal Presentation — technika wyświetlania ekranu, blokująca interakcję z poprzednim kontekstem do zamknięcia okna modalnego.
  • iOS używa UIModalPresentationStyle z wariantami .fullScreen, .pageSheet, .formSheet i .automatic.
  • Android realizuje modalność przez DialogFragment, BottomSheetDialogFragment i Activity z flagami Intent.
  • SwiftUI udostępnia modyfikatory .sheet i .fullScreenCover dla deklaratywnej prezentacji modalnej.
  • Jetpack Compose używa Dialog i ModalBottomSheet do tworzenia interfejsów modalnych.

Co to jest Modal Presentation?

Modal Presentation — to wzorzec nawigacji, w którym nowy ekran pojawia się nad bieżącym, tymczasowo blokując interakcję z rodzicielskim kontekstem. Użytkownik musi jawnie zakończyć zadanie modalne (anulowanie, zapisanie, zamknięcie), aby wrócić do poprzedniego stanu.

Modalność rozwiązuje zadanie poznawcze: skupia uwagę użytkownika na jednej czynności bez rozpraszania resztą interfejsu. Jest to krytycznie ważne dla formularzy rejestracyjnych, okien dialogowych potwierdzenia, wyboru plików i autoryzacji przez zewnętrzne serwisy. Human Interface Guidelines Apple zalecają używanie modalności tylko dla zadań wymagających ukończenia przed kontynuowaniem pracy.

W przeciwieństwie do modalnych okien internetowych, mobilna Modal Presentation może być pełnoekranowa (zajmować cały ekran) lub częściowa (Page Sheet, Bottom Sheet). Wybór typu zależy od kontekstu zadania i platformowych konwencji. iOS skłania się ku Page Sheet dla większości scenariuszy, pozostawiając Full Screen dla odtwarzaczy wideo i edytorów zdjęć.

Push Presentation (nawigacja stosowa) dodaje ekran do stosu nawigacyjnego i automatycznie pokazuje przycisk wstecz. Użytkownik może wrócić do poprzedniego ekranu w dowolnym momencie. Modal Presentation, przeciwnie, zakłada jawne zakończenie: przycisk wstecz albo nie istnieje, albo zamyka okno modalne, a nie wraca do poprzedniego ekranu.

Główne różnice między prezentacją modalną a push: Modal Presentation blokuje nawigację wstecz bez utraty danych, wymaga działania w celu zamknięcia (Save, Cancel, Done) i zazwyczaj przedstawia oddzielne zadanie. Push Presentation zachowuje hierarchię nawigacji, automatycznie dodaje przycisk powrotu i nadaje się do sekwencyjnego przeglądania treści.

CechaModal PresentationPush Presentation
Blokada wsteczTak, wymagane jawne działanieNie, przycisk wstecz zawsze dostępny
Typowe zastosowanieFormularze, autoryzacja, wybórSzczegółowy przegląd, nawigacja
AnimacjaZ dołu do góry (iOS), przesunięcie (Android)Z prawej do lewej (iOS)
Stos nawigacjiNie dodawany do głównego stosuDodawany do stosu

W praktyce wybór między Modal a Push zależy od kontekstu. Zaleca się używanie modalności dla zadań, które użytkownik musi ukończyć przed kontynuowaniem, a Push — do sekwencyjnego przeglądania treści. Mieszanie wzorców na jednym ekranie prowadzi do zamieszania i pogarsza UX.

Prezentacja modalna w iOS: UIKit i SwiftUI

iOS oferuje kilka stylów prezentacji modalnej przez wyliczenie UIModalPresentationStyle. UIKit obsługuje .fullScreen (pełny ekran), .pageSheet (karta z odstępem u góry), .formSheet (wyśrodkowane okno na iPad) i .automatic (wybór przez system na podstawie kontekstu). Od iOS 13 domyślnym stylem stał się .automatic, który dla iPhone wybiera .pageSheet.

UIViewController.present

Podstawowa metoda UIKit dla prezentacji modalnej — present(_:animated:completion:). Kontroler wywołujący metodę staje się presentingViewController, a nowy — presentedViewController. Zamknięcie wykonuje się przez dismiss(animated:completion:). SwiftUI udostępnia modyfikator .sheet dla analogicznego zachowania.

SwiftUI .sheet

Deklaratywne podejście SwiftUI używa modyfikatorów .sheet i .fullScreenCover. Pierwszy tworzy Page Sheet, drugi — pełnoekranową prezentację modalną. Oba przyjmują binding na Bool lub identyfikowalny obiekt, który zarządza widocznością okna modalnego. Zamknięcie następuje przy ustawieniu binding na false lub wywołaniu dismiss z environment.

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

    var body: some View {
        Button("Otwórz formularz") {
            showModal = true
        }
        .sheet(isPresented: $showModal) {
            RegistrationForm()
        }
    }
}

struct RegistrationForm: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Button("Zapisz") { dismiss() }
    }
}

Prezentacja modalna w Android: Fragment i Compose

Android nie ma jednego API do prezentacji modalnej jak iOS. Zamiast tego platforma oferuje kilka mechanizmów: DialogFragment dla okien dialogowych, BottomSheetDialogFragment dla paneli dolnych i Activity z flagami NEW_TASK i CLEAR_TOP dla ekranów modalnych. W Jetpack Compose pojawił się jednolity komponent Dialog dla wszystkich typów okien modalnych.

DialogFragment

DialogFragment — podstawowa klasa dla okien modalnych w Android SDK. Zarządza cyklem życia okna dialogowego, obsługuje obrót ekranu i zapisuje stan. Fragment wyświetla się nad Activity bez blokowania stosu nawigacyjnego. Zamknięcie wykonuje się przez dismiss() lub kliknięcie poza obszarem okna dialogowego, jeśli setCancelable(true).

Modal Bottom Sheet

BottomSheetDialogFragment wyświetla okno modalne jako panel podnoszący się z dołu. Ten wzorzec jest popularny w Material Design do wyboru opcji, udostępniania i szybkich działań. BottomSheet może mieć stałą wysokość lub być rozszerzalny (peek height + full height). W Compose używany jest ModalBottomSheet z biblioteki Material3.

kotlin
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
    Dialog(onDismissRequest = onDismiss) {
        Card(
            modifier = Modifier.padding(16.dp)
        ) {
            Column {
                Text("Formularz modalny", style = MaterialTheme.typography.headlineSmall)
                Button(onClick = onDismiss) {
                    Text("Zamknij")
                }
            }
        }
    }
}

Najlepsze praktyki prezentacji modalnej

Okna modalne — potężne narzędzie UX, ale ich nadmierne używanie pogarsza doświadczenie użytkownika. Apple HIG i Google Material Design zgadzają się w zaleceniach: modalność powinna być stosowana do zadań wymagających skupienia i nie przekraczać 20% ogólnej liczby działań nawigacyjnych.

Kiedy używać prezentacji modalnej

Okna modalne nadają się do scenariuszy: wprowadzanie danych (formularze rejestracyjne, profilu), potwierdzanie (usuwanie, wysyłanie), wybór (picker daty, menedżer plików) i autoryzacja (OAuth, Firebase Auth). Jeśli zadanie zajmuje mniej niż 30 sekund i wymaga blokady kontekstu — wybieraj modalność.

Czego unikać

Nie używaj prezentacji modalnej do: sekwencyjnego przeglądania treści (użyj Push), wyświetlania błędów (użyj Toast lub Snackbar), reklam i ofert promocyjnych bez jawnego żądania użytkownika. Material Design zaleca unikanie zagnieżdżonych okien modalnych — dezorientuje to użytkownika i narusza hierarchię nawigacji.

Dla okien modalnych z polami tekstowymi należy obowiązkowo obsługiwać utratę focusu klawiatury. Przy pojawieniu się klawiatury okno modalne powinno przesuwać się w górę, aby użytkownik widział wpisywany tekst. UIKeyboardWillShowNotification w iOS i adjustResize w Android rozwiązują to zadanie.

Przykłady kodu w Swift i Kotlin

Rozważmy implementację prezentacji modalnej na obu platformach. Swift przykład pokazuje konfigurację UIModalPresentationStyle.pageSheet z delegatem do obsługi zamknięcia. Kotlin przykład demonstruje DialogFragment z niestandardowym layoutem i zapisywaniem stanu.

swift
let modalVC = ModalViewController()
modalVC.modalPresentationStyle = .pageSheet

if let sheet = modalVC.sheetPresentationController {
    sheet.detents = [.medium(), .large()]
    sheet.prefersGrabberVisible = true
}

modalVC.presentationController?.delegate = self
present(modalVC, animated: true)

// MARK: - UIAdaptivePresentationControllerDelegate
extension ViewController: UIAdaptivePresentationControllerDelegate {
    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
        print("Okno modalne zamknięte")
    }
}
kotlin
class ModalDialogFragment : DialogFragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_modal, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        view.findViewById<Button>(R.id.closeButton).setOnClickListener {
            dismiss()
        }
    }
}

Często zadawane pytania

Kiedy należy używać Modal Presentation zamiast Push?

Używaj Modal Presentation do zadań wymagających skupienia, które użytkownik musi ukończyć przed kontynuowaniem: formularze, potwierdzenia, autoryzacja. Push nadaje się do sekwencyjnego przeglądania treści, gdzie użytkownik może swobodnie wracać. Okno modalne nie powinno zawierać nawigacji wewnątrz siebie.

Jaki styl prezentacji modalnej wybrać w iOS?

Od iOS 13 domyślny styl .automatic wybiera .pageSheet dla iPhone. .pageSheet nadaje się do większości scenariuszy (formularze, szczegóły). .fullScreen — do treści multimedialnych (wideo, edytory zdjęć). .formSheet — dla aplikacji na iPad, gdzie potrzebne jest wyśrodkowane okno.

Jak zaimplementować okno modalne w Jetpack Compose?

Jetpack Compose udostępnia komponent Dialog dla prostych okien modalnych i ModalBottomSheet dla paneli dolnych. Dialog przyjmuje onDismissRequest i treść w stylu Compose. Do zapisywania stanu używaj rememberSaveable wewnątrz okna dialogowego.

Czy można zagnieżdżać okna modalne w sobie?

Apple HIG i Material Design nie zalecają zagnieżdżonych okien modalnych. Jeśli użytkownik otwiera okno modalne na innym oknie modalnym, traci kontekst i może się pogubić w hierarchii. Zamiast zagnieżdżania używaj Step Indicator lub wzorca Wizard z jednym oknem modalnym.

Jak obsłużyć zamknięcie okna modalnego przy utracie danych?

Używaj UIAdaptivePresentationControllerDelegate w iOS (metoda presentationControllerShouldDismiss) lub OnBackPressedDispatcher w Android. W przypadku niezapisanych danych pokazuj AlertDialog z opcjami: zapisz, anuluj zmiany, zostań na ekranie. Zapobiega to przypadkowej utracie danych przez użytkownika.

Podsumowanie

  • Modal Presentation — wzorzec nawigacji blokujący interakcję z rodzicielskim kontekstem do ukończenia zadania.
  • iOS obsługuje .fullScreen, .pageSheet, .formSheet przez UIModalPresentationStyle i .sheet w SwiftUI.
  • Android realizuje modalność przez DialogFragment, BottomSheet i Dialog w Jetpack Compose.
  • Modal różni się od Push blokadą wstecz i wymogiem jawnego działania w celu zamknięcia.
  • Okna modalne nie powinny przekraczać 20% scenariuszy nawigacyjnych i nie powinny być zagnieżdżane.
  • Utratę danych przy zamykaniu okna modalnego należy zapobiegać przez delegaty i okna dialogowe potwierdzenia.
  • Zaleca się wybór Page Sheet w iOS i DialogFragment w Android dla standardowych zadań modalnych.

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ż