Modal Presentation — způsob zobrazení obrazovky nad aktuálním kontextem s blokováním interakce s předchozím rozhraním. V mobilním vývoji se modální okna používají pro fokusované úkoly: zadávání dat, potvrzování akcí, autentizace a výběr možností. Podle Apple HIG, 2025 by modální prezentace neměly zabírat více než 20 % navigačních scénářů v aplikaci. V Androidu je modalita implementována pomocí DialogFragment, BottomSheet a Activity s určitými launch flagy.
Hlavní body
Modal Presentation — je navigační vzor, při kterém se nová obrazovka objeví nad aktuální a dočasně blokuje interakci s rodičovským obsahem. Uživatel musí explicitně dokončit modální úkol (zrušit, uložit, zavřít), aby se vrátil do předchozího stavu.
Modalita řeší kognitivní úkol: soustředí pozornost uživatele na jednu akci bez rozptylování zbytkem rozhraní. To je kritické pro registrační formuláře, potvrzovací dialogy, výběr souborů a autentizaci prostřednictvím služeb třetích stran. Human Interface Guidelines od Apple doporučují používat modalitu pouze pro úkoly, které vyžadují dokončení před pokračováním v práci.
Na rozdíl od webových modálních oken může být mobilní Modal Presentation celoobrazovková (zabírá celou obrazovku) nebo částečná (Page Sheet, Bottom Sheet). Výběr typu závisí na kontextu úkolu a platformních konvencích. iOS tíhne k Page Sheet pro většinu scénářů, ponechává Full Screen pro přehrávače videa a fotoeditory.
Push Presentation (zásobníková navigace) přidává obrazovku do navigačního zásobníku a automaticky zobrazuje tlačítko zpět. Uživatel se může kdykoli vrátit na předchozí obrazovku. Modal Presentation naopak vyžaduje explicitní dokončení: tlačítko zpět buď chybí, nebo zavírá modální okno, nikoli se vrací na předchozí obrazovku.
Hlavní rozdíly mezi modální a push prezentací: Modal Presentation blokuje navigaci zpět bez ztráty dat, vyžaduje akci pro zavření (Save, Cancel, Done) a obvykle představuje samostatný úkol. Push Presentation zachovává hierarchii navigace, automaticky přidává tlačítko zpět a je vhodná pro sekvenční prohlížení obsahu.
| Vlastnost | Modal Presentation | Push Presentation |
|---|---|---|
| Blokování zpět | Ano, vyžaduje explicitní akci | Ne, tlačítko zpět vždy dostupné |
| Typické použití | Formuláře, autentizace, výběr | Detailní prohlížení, navigace |
| Animace | Zdola nahoru (iOS), posuv (Android) | Zprava doleva (iOS) |
| Zásobník navigace | Nepřidává se do hlavního zásobníku | Přidává se do zásobníku |
V praxi závisí výběr mezi Modal a Push na kontextu. Doporučuje se používat modalitu pro úkoly, které musí uživatel dokončit před pokračováním, a Push pro sekvenční prozkoumávání obsahu. Míchání vzorů na jedné obrazovce vede k zmatení a zhoršuje UX.
iOS nabízí několik stylů modální prezentace prostřednictvím výčtu UIModalPresentationStyle. UIKit podporuje .fullScreen (celá obrazovka), .pageSheet (karta s okrajem nahoře), .formSheet (centrované okno na iPadu) a .automatic (výběr systémem na základě kontextu). Od iOS 13 se výchozím stylem stal .automatic, který pro iPhone volí .pageSheet.
Základní metoda UIKit pro modální prezentaci — present(_:animated:completion:). Kontroler, který metodu volá, se stává presentingViewController a nový — presentedViewController. Zavření se provádí pomocí dismiss(animated:completion:). SwiftUI poskytuje modifikátor .sheet pro podobné chování.
Deklarativní přístup SwiftUI používá modifikátory .sheet a .fullScreenCover. První vytváří Page Sheet, druhý — celoobrazovkovou modální prezentaci. Oba přijímají binding na Bool nebo identifikovatelný objekt, který řídí viditelnost modálního okna. Zavření nastane při nastavení binding na false nebo voláním dismiss z environment.
struct ContentView: View {
@State private var showModal = false
var body: some View {
Button("Otevřít formulář") {
showModal = true
}
.sheet(isPresented: $showModal) {
RegistrationForm()
}
}
}
struct RegistrationForm: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("Uložit") { dismiss() }
}
}
Android nemá jednotné API pro modální prezentaci jako iOS. Místo toho platforma nabízí několik mechanismů: DialogFragment pro dialogová okna, BottomSheetDialogFragment pro spodní panely a Activity s flagy NEW_TASK a CLEAR_TOP pro modální obrazovky. V Jetpack Compose se objevila jednotná komponenta Dialog pro všechny typy modálních oken.
DialogFragment — základní třída pro modální okna v Android SDK. Spravuje životní cyklus dialogu, zpracovává otáčení obrazovky a ukládá stav. Fragment se zobrazuje nad Activity bez blokování navigačního zásobníku. Zavření se provádí pomocí dismiss() nebo kliknutím mimo oblast dialogu, pokud je setCancelable(true).
BottomSheetDialogFragment zobrazuje modální okno jako panel zvedající se zdola. Tento vzor je populární v Material Design pro výběr možností, sdílení a rychlé akce. BottomSheet může mít pevnou výšku nebo být rozšiřitelný (peek height + full height). V Compose se používá ModalBottomSheet z knihovny Material3.
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
Dialog(onDismissRequest = onDismiss) {
Card(
modifier = Modifier.padding(16.dp)
) {
Column {
Text("Modální formulář", style = MaterialTheme.typography.headlineSmall)
Button(onClick = onDismiss) {
Text("Zavřít")
}
}
}
}
}
Modální okna — mocný nástroj UX, ale jejich nadměrné používání zhoršuje uživatelský zážitek. Apple HIG a Google Material Design se shodují v doporučeních: modalita by měla být aplikována pro fokusované úkoly a neměla by přesahovat 20 % celkového počtu navigačních akcí.
Modální okna jsou vhodná pro scénáře: zadávání dat (registrační formuláře, profil), potvrzování (mazání, odesílání), výběr (výběr data, správce souborů) a autentizace (OAuth, Firebase Auth). Pokud úkol trvá méně než 30 sekund a vyžaduje blokování kontextu — zvolte modalitu.
Nepoužívejte modální prezentaci pro: sekvenční prohlížení obsahu (použijte Push), zobrazování chyb (použijte Toast nebo Snackbar), reklamy a propagační nabídky bez explicitního požadavku uživatele. Material Design doporučuje vyhnout se vnořeným modálním oknům — to dezorientuje uživatele a narušuje hierarchii navigace.
U modálních oken s textovými poli nezapomeňte zpracovat ztrátu fokusu klávesnice. Při zobrazení klávesnice by se modální okno mělo posunout nahoru, aby uživatel viděl zadávaný text. UIKeyboardWillShowNotification v iOS a adjustResize v Androidu tento problém řeší.
Podívejme se na implementaci modální prezentace na obou platformách. Příklad v Swift ukazuje nastavení UIModalPresentationStyle.pageSheet s delegátem pro zpracování zavření. Příklad v Kotlin demonstruje DialogFragment s vlastním layoutem a ukládáním stavu.
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("Modální okno zavřeno")
}
}
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()
}
}
}
Často kladené otázky
Použijte Modal Presentation pro fokusované úkoly, které musí uživatel dokončit před pokračováním: formuláře, potvrzení, autentizace. Push je vhodný pro sekvenční prohlížení obsahu, kde se uživatel může volně vracet zpět. Modální okno by nemělo obsahovat navigaci uvnitř sebe.
Od iOS 13 výchozí styl .automatic volí pro iPhone .pageSheet. .pageSheet je vhodný pro většinu scénářů (formuláře, detaily). .fullScreen — pro mediální obsah (video, fotoeditory). .formSheet — pro iPad aplikace, kde je potřeba centrované okno.
Jetpack Compose poskytuje komponentu Dialog pro jednoduchá modální okna a ModalBottomSheet pro spodní panely. Dialog přijímá onDismissRequest a obsah ve stylu Compose. Pro ukládání stavu použijte rememberSaveable uvnitř dialogu.
Apple HIG a Material Design nedoporučují vnořená modální okna. Pokud uživatel otevře modální okno nad jiným modálním oknem, ztrácí kontext a může se zmást v hierarchii. Místo vnořování použijte Step Indicator nebo vzor Wizard s jedním modálním oknem.
Použijte UIAdaptivePresentationControllerDelegate v iOS (metoda presentationControllerShouldDismiss) nebo OnBackPressedDispatcher v Androidu. Při neuložených datech zobrazte AlertDialog s možnostmi: uložit, zrušit změny, zůstat na obrazovce. Tím se zabrání náhodné ztrátě dat uživatelem.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také