Modal Presentation — τρόπος εμφάνισης οθόνης πάνω από το τρέχον πλαίσιο με αποκλεισμό αλληλεπίδρασης με την προηγούμενη διεπαφή. Στην κινητή ανάπτυξη, τα modal παράθυρα χρησιμοποιούνται για εστιασμένες εργασίες: εισαγωγή δεδομένων, επιβεβαίωση ενεργειών, πιστοποίηση ταυτότητας και επιλογή επιλογών. Σύμφωνα με το Apple HIG, 2025, οι modal παρουσιάσεις δεν πρέπει να καταλαμβάνουν περισσότερο από το 20% των σεναρίων πλοήγησης στην εφαρμογή. Στο Android, η modalità υλοποιείται μέσω DialogFragment, BottomSheet και Activity με συγκεκριμένα launch flags.
Βασικά σημεία
Modal Presentation — είναι ένα μοτίβο πλοήγησης όπου μια νέα οθόνη εμφανίζεται πάνω από την τρέχουσα, αποκλείοντας προσωρινά την αλληλεπίδραση με το γονικό περιεχόμενο. Ο χρήστης πρέπει να ολοκληρώσει ρητά τη modal εργασία (ακύρωση, αποθήκευση, κλείσιμο) για να επιστρέψει στην προηγούμενη κατάσταση.
Η modalità λύνει μια γνωστική εργασία: εστιάζει την προσοχή του χρήστη σε μία μόνο ενέργεια χωρίς απόσπαση από την υπόλοιπη διεπαφή. Αυτό είναι κρίσιμο για φόρμες εγγραφής, διαλόγους επιβεβαίωσης, επιλογή αρχείων και πιστοποίηση ταυτότητας μέσω τρίτων υπηρεσιών. Οι Human Interface Guidelines της Apple συνιστούν τη χρήση της modalità μόνο για εργασίες που απαιτούν ολοκλήρωση πριν από τη συνέχιση της εργασίας.
Σε αντίθεση με τα web modal παράθυρα, η κινητή Modal Presentation μπορεί να είναι πλήρους οθόνης (καταλαμβάνει όλη την οθόνη) ή μερική (Page Sheet, Bottom Sheet). Η επιλογή τύπου εξαρτάται από το πλαίσιο της εργασίας και τις συμβάσεις πλατφόρμας. Το iOS τείνει προς το Page Sheet για τα περισσότερα σενάρια, αφήνοντας το Full Screen για προγράμματα αναπαραγωγής βίντεο και επεξεργαστές φωτογραφιών.
Push Presentation (πλοήγηση στοίβας) προσθέτει την οθόνη στη στοίβα πλοήγησης και εμφανίζει αυτόματα το κουμπί πίσω. Ο χρήστης μπορεί να επιστρέψει στην προηγούμενη οθόνη οποιαδήποτε στιγμή. Η Modal Presentation, αντίθετα, απαιτεί ρητή ολοκλήρωση: το κουμπί πίσω είτε λείπει είτε κλείνει το modal παράθυρο, αντί να επιστρέφει στην προηγούμενη οθόνη.
Κύριες διαφορές μεταξύ modal και push παρουσίασης: Modal Presentation αποκλείει την πλοήγηση προς τα πίσω χωρίς απώλεια δεδομένων, απαιτεί ενέργεια για κλείσιμο (Save, Cancel, Done) και συνήθως αντιπροσωπεύει ξεχωριστή εργασία. Push Presentation διατηρεί την ιεραρχία πλοήγησης, προσθέτει αυτόματα κουμπί επιστροφής και είναι κατάλληλη για διαδοχική προβολή περιεχομένου.
| Χαρακτηριστικό | Modal Presentation | Push Presentation |
|---|---|---|
| Αποκλεισμός πίσω | Ναι, απαιτεί ρητή ενέργεια | Όχι, το κουμπί πίσω είναι πάντα διαθέσιμο |
| Τυπική χρήση | Φόρμες, πιστοποίηση, επιλογή | Λεπτομερής προβολή, πλοήγηση |
| Κινούμενο σχέδιο | Από κάτω προς τα πάνω (iOS), ολίσθηση (Android) | Από δεξιά προς τα αριστερά (iOS) |
| Στοίβα πλοήγησης | Δεν προστίθεται στην κύρια στοίβα | Προστίθεται στη στοίβα |
Στην πράξη, η επιλογή μεταξύ Modal και Push εξαρτάται από το πλαίσιο. Συνιστάται η χρήση modalità για εργασίες που πρέπει να ολοκληρώσει ο χρήστης πριν συνεχίσει, και Push για τη διαδοχική εξερεύνηση περιεχομένου. Η ανάμειξη μοτίβων στην ίδια οθόνη οδηγεί σε σύγχυση και επιδεινώνει την UX.
iOS προσφέρει διάφορα στυλ modal παρουσίασης μέσω της απαρίθμησης UIModalPresentationStyle. Το UIKit υποστηρίζει .fullScreen (πλήρης οθόνη), .pageSheet (κάρτα με περιθώριο πάνω), .formSheet (κεντραρισμένο παράθυρο σε iPad) και .automatic (επιλογή από το σύστημα βάσει πλαισίου). Από το iOS 13, το προεπιλεγμένο στυλ έγινε .automatic, το οποίο για το iPhone επιλέγει .pageSheet.
Η βασική μέθοδος UIKit για modal παρουσίαση — present(_:animated:completion:). Ο ελεγκτής που καλεί τη μέθοδο γίνεται presentingViewController, και ο νέος — presentedViewController. Το κλείσιμο γίνεται μέσω dismiss(animated:completion:). Το SwiftUI παρέχει τον τροποποιητή .sheet για παρόμοια συμπεριφορά.
Η δηλωτική προσέγγιση του SwiftUI χρησιμοποιεί τους τροποποιητές .sheet και .fullScreenCover. Ο πρώτος δημιουργεί Page Sheet, ο δεύτερος — modal παρουσίαση πλήρους οθόνης. Και οι δύο δέχονται ένα binding σε Bool ή ένα αναγνωρίσιμο αντικείμενο που ελέγχει την ορατότητα του modal παραθύρου. Το κλείσιμο συμβαίνει όταν το binding τεθεί σε false ή με κλήση του dismiss από το environment.
struct ContentView: View {
@State private var showModal = false
var body: some View {
Button("Άνοιγμα φόρμας") {
showModal = true
}
.sheet(isPresented: $showModal) {
RegistrationForm()
}
}
}
struct RegistrationForm: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("Αποθήκευση") { dismiss() }
}
}
Android δεν έχει ενιαίο API για modal παρουσίαση όπως το iOS. Αντίθετα, η πλατφόρμα προσφέρει διάφορους μηχανισμούς: DialogFragment για παράθυρα διαλόγου, BottomSheetDialogFragment για κάτω πάνελ και Activity με σημαίες NEW_TASK και CLEAR_TOP για modal οθόνες. Στο Jetpack Compose εμφανίστηκε ένα ενιαίο στοιχείο Dialog για όλους τους τύπους modal παραθύρων.
DialogFragment — η βασική κλάση για modal παράθυρα στο Android SDK. Διαχειρίζεται τον κύκλο ζωής του διαλόγου, επεξεργάζεται την περιστροφή οθόνης και αποθηκεύει κατάσταση. Το Fragment εμφανίζεται πάνω από το Activity χωρίς να αποκλείει τη στοίβα πλοήγησης. Το κλείσιμο γίνεται μέσω dismiss() ή κλικ εκτός της περιοχής διαλόγου εάν setCancelable(true).
BottomSheetDialogFragment εμφανίζει το modal παράθυρο ως πάνελ που ανυψώνεται από κάτω. Αυτό το μοτίβο είναι δημοφιλές στο Material Design για επιλογή επιλογών, κοινή χρήση και γρήγορες ενέργειες. Το BottomSheet μπορεί να έχει σταθερό ύψος ή επεκτάσιμο (peek height + full height). Στο Compose χρησιμοποιείται το ModalBottomSheet από τη βιβλιοθήκη Material3.
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
Dialog(onDismissRequest = onDismiss) {
Card(
modifier = Modifier.padding(16.dp)
) {
Column {
Text("Modal φόρμα", style = MaterialTheme.typography.headlineSmall)
Button(onClick = onDismiss) {
Text("Κλείσιμο")
}
}
}
}
}
Τα modal παράθυρα — ισχυρό εργαλείο UX, αλλά η υπερβολική χρήση τους επιδεινώνει την εμπειρία χρήστη. Οι Apple HIG και Google Material Design συμφωνούν στις συστάσεις: η modalità πρέπει να εφαρμόζεται για εστιασμένες εργασίες και να μην υπερβαίνει το 20% του συνολικού αριθμού ενεργειών πλοήγησης.
Τα modal παράθυρα είναι κατάλληλα για σενάρια: εισαγωγή δεδομένων (φόρμες εγγραφής, προφίλ), επιβεβαίωση (διαγραφή, αποστολή), επιλογή (επιλογέας ημερομηνίας, διαχείριση αρχείων) και πιστοποίηση ταυτότητας (OAuth, Firebase Auth). Εάν η εργασία διαρκεί λιγότερο από 30 δευτερόλεπτα και απαιτεί αποκλεισμό πλαισίου — επιλέξτε τη modalità.
Μην χρησιμοποιείτε modal παρουσίαση για: διαδοχική προβολή περιεχομένου (χρησιμοποιήστε Push), εμφάνιση σφαλμάτων (χρησιμοποιήστε Toast ή Snackbar), διαφημίσεις και προσφορές χωρίς ρητό αίτημα χρήστη. Το Material Design συνιστά την αποφυγή ένθετων modal παραθύρων — αυτό αποπροσανατολίζει τον χρήστη και παραβιάζει την ιεραρχία πλοήγησης.
Για modal παράθυρα με πεδία κειμένου, φροντίστε να χειρίζεστε την απώλεια εστίασης πληκτρολογίου. Όταν εμφανίζεται το πληκτρολόγιο, το modal παράθυρο πρέπει να μετακινείται προς τα πάνω ώστε ο χρήστης να βλέπει το κείμενο που εισάγει. Η UIKeyboardWillShowNotification στο iOS και το adjustResize στο Android λύνουν αυτό το πρόβλημα.
Ας εξετάσουμε την υλοποίηση της modal παρουσίασης και στις δύο πλατφόρμες. Το παράδειγμα Swift δείχνει τη ρύθμιση του UIModalPresentationStyle.pageSheet με εκπρόσωπο για τον χειρισμό του κλεισίματος. Το παράδειγμα Kotlin παρουσιάζει ένα DialogFragment με προσαρμοσμένη διάταξη και αποθήκευση κατάστασης.
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("Modal παράθυρο έκλεισε")
}
}
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()
}
}
}
Συχνές ερωτήσεις
Χρησιμοποιήστε Modal Presentation για εστιασμένες εργασίες που πρέπει να ολοκληρώσει ο χρήστης πριν συνεχίσει: φόρμες, επιβεβαιώσεις, πιστοποίηση. Το Push είναι κατάλληλο για διαδοχική προβολή περιεχομένου, όπου ο χρήστης μπορεί να επιστρέψει ελεύθερα. Το modal παράθυρο δεν πρέπει να περιέχει πλοήγηση εντός του.
Από το iOS 13, το προεπιλεγμένο στυλ .automatic επιλέγει .pageSheet για iPhone. .pageSheet είναι κατάλληλο για τα περισσότερα σενάρια (φόρμες, λεπτομέρειες). .fullScreen — για περιεχόμενο πολυμέσων (βίντεο, επεξεργαστές φωτογραφιών). .formSheet — για εφαρμογές iPad όπου χρειάζεται κεντραρισμένο παράθυρο.
Jetpack Compose παρέχει το στοιχείο Dialog για απλά modal παράθυρα και το ModalBottomSheet για κάτω πάνελ. Το Dialog δέχεται onDismissRequest και περιεχόμενο σε στυλ Compose. Για αποθήκευση κατάστασης, χρησιμοποιήστε rememberSaveable μέσα στον διάλογο.
Οι Apple HIG και Material Design δεν συνιστούν ένθετα modal παράθυρα. Εάν ο χρήστης ανοίξει ένα modal παράθυρο πάνω από ένα άλλο modal παράθυρο, χάνει το πλαίσιο και μπορεί να μπερδευτεί στην ιεραρχία. Αντί για ένθεση, χρησιμοποιήστε Step Indicator ή μοτίβο Wizard με ένα modal παράθυρο.
Χρησιμοποιήστε UIAdaptivePresentationControllerDelegate στο iOS (μέθοδος presentationControllerShouldDismiss) ή OnBackPressedDispatcher στο Android. Σε περίπτωση μη αποθηκευμένων δεδομένων, εμφανίστε ένα AlertDialog με επιλογές: αποθήκευση, ακύρωση αλλαγών, παραμονή στην οθόνη. Αυτό αποτρέπει την τυχαία απώλεια δεδομένων από τον χρήστη.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης