Modal Presentation — a képernyő megjelenítésének módja az aktuális kontextus felett, blokkolva az interakciót az előző interfésszel. A mobilfejlesztésben a modális ablakokat fókuszált feladatokhoz használják: adatbevitel, műveletek megerősítése, hitelesítés és opciók kiválasztása. Az Apple HIG, 2025 szerint a modális prezentációk nem foglalhatják el az alkalmazás navigációs forgatókönyveinek több mint 20%-át. Androidban a modalitás DialogFragment, BottomSheet és meghatározott launch-flag-ekkel rendelkező Activity segítségével valósul meg.
Főbb pontok
Modal Presentation — egy navigációs minta, amelyben egy új képernyő jelenik meg az aktuális felett, ideiglenesen blokkolva az interakciót a szülő tartalommal. A felhasználónak explicit módon be kell fejeznie a modális feladatot (mégse, mentés, bezárás), hogy visszatérjen az előző állapotba.
A modalitás egy kognitív feladatot old meg: a felhasználó figyelmét egyetlen műveletre összpontosítja anélkül, hogy a interfész többi része elterelné. Ez kritikus fontosságú a regisztrációs űrlapoknál, megerősítő párbeszédablakoknál, fájlválasztásnál és külső szolgáltatásokon keresztüli hitelesítésnél. Az Apple Human Interface Guidelines irányelvei azt ajánlják, hogy a modalitást csak olyan feladatokhoz használjuk, amelyek befejezése szükséges a munka folytatása előtt.
Ellentétben a webes modális ablakokkal, a mobil Modal Presentation lehet teljes képernyős (a teljes képernyőt elfoglalja) vagy részleges (Page Sheet, Bottom Sheet). A típus kiválasztása a feladat kontextusától és a platform konvencióitól függ. Az iOS a legtöbb forgatókönyvhöz a Page Sheet felé hajlik, a Full Screen-t a videolejátszók és fotószerkesztők számára megtartva.
Push Presentation (verem navigáció) hozzáadja a képernyőt a navigációs veremhez és automatikusan megjeleníti a vissza gombot. A felhasználó bármikor visszatérhet az előző képernyőre. A Modal Presentation ezzel szemben explicit befejezést igényel: a vissza gomb vagy hiányzik, vagy bezárja a modális ablakot, nem pedig visszatér az előző képernyőre.
A modális és push prezentáció közötti fő különbségek: Modal Presentation blokkolja a visszanavigációt adatvesztés nélkül, műveletet igényel a bezáráshoz (Save, Cancel, Done) és általában külön feladatot képvisel. Push Presentation megtartja a navigációs hierarchiát, automatikusan hozzáadja a visszatérés gombot és alkalmas a tartalom szekvenciális megtekintésére.
| Jellemző | Modal Presentation | Push Presentation |
|---|---|---|
| Visszablokkolás | Igen, explicit művelet szükséges | Nem, a vissza gomb mindig elérhető |
| Jellemző használat | Űrlapok, hitelesítés, kiválasztás | Részletes megtekintés, navigáció |
| Animáció | Alulról felfelé (iOS), csúsztatás (Android) | Jobbról balra (iOS) |
| Navigációs verem | Nem kerül a fő verembe | Belekerül a verembe |
A gyakorlatban a Modal és Push közötti választás a kontextustól függ. Ajánlott a modalitást olyan feladatokhoz használni, amelyeket a felhasználónak be kell fejeznie a folytatás előtt, a Push-t pedig a tartalom szekvenciális felfedezéséhez. A minták keverése egy képernyőn zavart okoz és rontja az UX-et.
iOS több modális prezentációs stílust kínál a UIModalPresentationStyle felsoroláson keresztül. A UIKit támogatja a .fullScreen (teljes képernyő), .pageSheet (kártya felső margóval), .formSheet (középre igazított ablak iPad-en) és .automatic (rendszer általi választás kontextus alapján) lehetőségeket. Az iOS 13-tól kezdve az alapértelmezett stílus .automatic lett, amely iPhone esetén a .pageSheet-et választja.
A UIKit alapmódszere a modális prezentációhoz — present(_:animated:completion:). A metódust meghívó kontroller lesz a presentingViewController, az új pedig a presentedViewController. A bezárás a dismiss(animated:completion:) segítségével történik. A SwiftUI a .sheet módosítót biztosítja hasonló viselkedéshez.
A SwiftUI deklaratív megközelítése a .sheet és .fullScreenCover módosítókat használja. Az első Page Sheet-et hoz létre, a második — teljes képernyős modális prezentációt. Mindkettő elfogad egy binding-ot Bool-ra vagy egy azonosítható objektumra, amely a modális ablak láthatóságát vezérli. A bezárás akkor történik, amikor a binding false-ra van állítva, vagy a dismiss meghívásra kerül a környezetből.
struct ContentView: View {
@State private var showModal = false
var body: some View {
Button("Űrlap megnyitása") {
showModal = true
}
.sheet(isPresented: $showModal) {
RegistrationForm()
}
}
}
struct RegistrationForm: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("Mentés") { dismiss() }
}
}
Android nem rendelkezik egységes API-val a modális prezentációhoz, mint az iOS. Ehelyett a platform több mechanizmust kínál: DialogFragment a párbeszédablakokhoz, BottomSheetDialogFragment az alsó panelekhez és Activity NEW_TASK és CLEAR_TOP flag-ekkel a modális képernyőkhöz. A Jetpack Compose-ban megjelent egy egységes Dialog komponens minden típusú modális ablakhoz.
DialogFragment — az alaposztály a modális ablakokhoz az Android SDK-ban. Kezeli a párbeszédablak életciklusát, feldolgozza a képernyőelforgatást és menti az állapotot. A Fragment az Activity felett jelenik meg anélkül, hogy blokkolná a navigációs vermet. A bezárás a dismiss() segítségével vagy a párbeszédablakon kívüli kattintással történik, ha setCancelable(true).
BottomSheetDialogFragment a modális ablakot alulról felemelkedő panelként jeleníti meg. Ez a minta népszerű a Material Design-ban opciók kiválasztásához, megosztáshoz és gyors műveletekhez. A BottomSheet lehet rögzített magasságú vagy bővíthető (peek height + full height). Compose-ban a Material3 könyvtár ModalBottomSheet komponensét használják.
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
Dialog(onDismissRequest = onDismiss) {
Card(
modifier = Modifier.padding(16.dp)
) {
Column {
Text("Modális űrlap", style = MaterialTheme.typography.headlineSmall)
Button(onClick = onDismiss) {
Text("Bezárás")
}
}
}
}
}
A modális ablakok — hatékony UX eszköz, de túlzott használatuk rontja a felhasználói élményt. Az Apple HIG és a Google Material Design egyetért az ajánlásokban: a modalitást fókuszált feladatokhoz kell alkalmazni, és nem haladhatja meg a navigációs műveletek teljes számának 20%-át.
A modális ablakok a következő forgatókönyvekhez alkalmasak: adatbevitel (regisztrációs űrlapok, profil), megerősítés (törlés, elküldés), kiválasztás (dátumválasztó, fájlkezelő) és hitelesítés (OAuth, Firebase Auth). Ha a feladat kevesebb mint 30 másodpercig tart és kontextusblokkolást igényel — válassza a modalitást.
Ne használjon modális prezentációt: tartalom szekvenciális megtekintéséhez (használjon Push-t), hibák megjelenítéséhez (használjon Toast-ot vagy Snackbar-t), reklámok és promóciós ajánlatok megjelenítéséhez a felhasználó explicit kérése nélkül. Material Design azt ajánlja, hogy kerüljük az egymásba ágyazott modális ablakokat — ez dezorientálja a felhasználót és megsérti a navigációs hierarchiát.
A szöveges mezőkkel rendelkező modális ablakoknál feltétlenül kezelje a billentyűzet fókuszának elvesztését. A billentyűzet megjelenésekor a modális ablaknak felfelé kell mozognia, hogy a felhasználó lássa a beírt szöveget. Az iOS-ben a UIKeyboardWillShowNotification és Androidban az adjustResize oldja meg ezt a problémát.
Vizsgáljuk meg a modális prezentáció implementációját mindkét platformon. A Swift példa az UIModalPresentationStyle.pageSheet beállítását mutatja delegáttal a bezárás kezeléséhez. A Kotlin példa egy DialogFragment-et mutat be egyedi layout-tal és állapotmentéssel.
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ális ablak bezárva")
}
}
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()
}
}
}
Gyakran ismételt kérdések
Használja a Modal Presentation-t olyan fókuszált feladatokhoz, amelyeket a felhasználónak be kell fejeznie a folytatás előtt: űrlapok, megerősítések, hitelesítés. A Push alkalmas a tartalom szekvenciális megtekintésére, ahol a felhasználó szabadon visszatérhet. A modális ablak nem tartalmazhat navigációt önmagán belül.
Az iOS 13-tól az alapértelmezett .automatic stílus a .pageSheet-et választja iPhone esetén. .pageSheet alkalmas a legtöbb forgatókönyvhöz (űrlapok, részletek). .fullScreen — médiatartalomhoz (videó, fotószerkesztők). .formSheet — iPad alkalmazásokhoz, ahol középre igazított ablak szükséges.
Jetpack Compose a Dialog komponenst biztosítja egyszerű modális ablakokhoz és a ModalBottomSheet-t az alsó panelekhez. A Dialog elfogadja az onDismissRequest és a Compose-stílusú tartalmat. Állapotmentéshez használja a rememberSaveable-t a dialógusablakon belül.
Az Apple HIG és a Material Design nem ajánlja az egymásba ágyazott modális ablakokat. Ha a felhasználó egy modális ablakot nyit meg egy másik modális ablak felett, elveszíti a kontextust és összezavarodhat a hierarchiában. Az egymásba ágyazás helyett használjon Step Indicator-t vagy Wizard mintát egyetlen modális ablakkal.
Használja a UIAdaptivePresentationControllerDelegate-et iOS-ben (presentationControllerShouldDismiss metódus) vagy az OnBackPressedDispatcher-t Androidban. Nem mentett adatok esetén jelenítsen meg egy AlertDialog-ot a következő opciókkal: mentés, módosítások elvetése, maradás a képernyőn. Ez megakadályozza a felhasználó általi véletlen adatvesztést.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is