Δείχνουμε τι είναι το Safe Area — η ασφαλής ζώνη οθόνης που εγγυάται ότι το περιεχόμενο δεν καλύπτεται από στοιχεία συστήματος: notch, Dynamic Island, StatusBar, ένδειξη Home και στρογγυλεμένες γωνίες. Το Safe Area είναι υποχρεωτικό στοιχείο προσαρμοστικής διάταξης σε iOS και Android, χωρίς το οποίο η διεπαφή μπορεί να εμφανίζεται εσφαλμένα σε συσκευές με εγκοπές. Σύμφωνα με το Apple HIG (2025), από την εμφάνιση του iPhone X το 2017, όλες οι εφαρμογές υποχρεούνται να χρησιμοποιούν το Safe Area Layout Guide.
Κύρια σημεία
Safe Area — είναι μια ορθογώνια περιοχή οθόνης στην οποία το περιεχόμενο είναι εγγυημένο ότι δεν καλύπτεται από στοιχεία υλικού και λογισμικού του συστήματος: η εγκοπή κάμερας (notch), το Dynamic Island, η γραμμή κατάστασης (StatusBar), ο δείκτης πλοήγησης χειρονομιών (Home Indicator), οι στρογγυλεμένες γωνίες οθόνης και το πλαίσιο πλοήγησης. Τα όρια του Safe Area αλλάζουν δυναμικά κατά την περιστροφή της συσκευής, την κλήση πληκτρολογίου ή την εκκίνηση Split View. Σύμφωνα με το Apple Human Interface Guidelines (2025), η αγνόηση του Safe Area θεωρείται σφάλμα σχεδιασμού και μπορεί να οδηγήσει σε απόρριψη της εφαρμογής κατά την αναθεώρηση.
Safe Area λύνει το πρόβλημα κατακερματισμού οθονών στο οικοσύστημα κινητών. Πριν από το iPhone X, όλα τα iPhone είχαν ορθογώνια οθόνη με τις ίδιες αναλογίες. Με την εμφάνιση του notch, ο αριθμός των παραλλαγών οθόνης αυξήθηκε σε 20+ — διαφορετικά μεγέθη εγκοπών, Dynamic Island, στρογγυλοποιήσεις, δείκτες. Το Safe Area αφαιρεί τον προγραμματιστή από αυτές τις διαφορές, παρέχοντας ένα ενιαίο API για προσαρμοστικές αποστάσεις. Σύμφωνα με το Apple Developer (2025), το iOS εφαρμόζει αυτόματα το Safe Area για την προβολή ρίζας, αλλά για UICollectionView και UIScrollView απαιτείται χειροκίνητη διαμόρφωση.
| Συσκευή | Τύπος εγκοπής | Πάνω απόσταση | Κάτω απόσταση | StatusBar |
|---|---|---|---|---|
| iPhone SE (3rd gen) | Όχι | 20px | 0px | Ναι |
| iPhone 13 Pro | Notch | 47px | 34px | Μέσα στο notch |
| iPhone 14 Pro | Dynamic Island | 59px | 34px | Μέσα στο DI |
| iPhone 16 Pro | Dynamic Island | 59px | 34px | Μέσα στο DI |
| Android Pixel 8 | Punch-hole (κάμερα) | 24px | 24px | Γραμμή κατάστασης |
Στο iOS το Safe Area υλοποιείται μέσω του SafeAreaLayoutGuide στο UIKit και του τροποποιητή safeAreaInset στο SwiftUI. Το SafeAreaLayoutGuide είναι ένας οδηγός διάταξης που προστίθεται σε κάθε UIView και ορίζει το ορθογώνιο ελεύθερο από στοιχεία συστήματος. Στο Interface Builder το Safe Area εμφανίζεται ως μπλε περιοχή. Το SwiftUI εφαρμόζει το Safe Area αυτόματα για τους περισσότερους περιέκτες, αλλά επιτρέπει την αγνόησή του μέσω .ignoresSafeArea().
// UIKit: SafeAreaLayoutGuide
let safeGuide = view.safeAreaLayoutGuide
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.topAnchor.constraint(
equalTo: safeGuide.topAnchor),
button.leadingAnchor.constraint(
equalTo: safeGuide.leadingAnchor),
button.trailingAnchor.constraint(
equalTo: safeGuide.trailingAnchor),
])
SafeAreaLayoutGuide στο UIKit ορίζει τέσσερα anchor — top, bottom, leading, trailing — που λαμβάνουν αυτόματα υπόψη το notch, StatusBar και Home Indicator. Αυτή η προσέγγιση λειτουργεί σε όλες τις συσκευές iOS, ξεκινώντας από iOS 11. Στο SwiftUI το ίδιο αποτέλεσμα επιτυγχάνεται μέσω του τροποποιητή περιεχομένου μέσα σε NavigationStack ή VStack — το SwiftUI εφαρμόζει αυτόματα το Safe Area Insets.
// SwiftUI: safeAreaInset και ignoresSafeArea
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
Text("Περιεχόμενο στο Safe Area")
.foregroundColor(.white)
Spacer()
}
}
.safeAreaInset(edge: .bottom) {
Text("Γραμμή στο κάτω μέρος της οθόνης")
.padding()
.background(.thinMaterial)
}
Στο SwiftUI .ignoresSafeArea() επιτρέπει στο φόντο να εκτείνεται πέρα από το Safe Area, και το .safeAreaInset(edge:) προσθέτει ένα προσαρμοσμένο πλαίσιο που μειώνει το Safe Area από την καθορισμένη πλευρά. Αυτό είναι το τυπικό μοτίβο για πλαίσια πλοήγησης, γραμμές εργαλείων και διαφημιστικά banners.
Στο Android το Safe Area υλοποιείται μέσω του WindowInsets (API 30+) και του WindowInsetsCompat (βιβλιοθήκη AndroidX). Το WindowInsets παρέχει αποστάσεις για Status Bar, Navigation Bar, IME (πληκτρολόγιο) και χειρονομίες συστήματος. Από το Android 10 (API 29), η Google συνιστά τη χρήση του WindowInsetsCompat.getInsets() με τύπο WindowInsetsCompat.Type.systemBars() για τη λήψη ενός ενιαίου συνόλου αποστάσεων για όλα τα στοιχεία συστήματος.
// Android: WindowInsets (Kotlin)
class MainActivity : AppCompatActivity() {
override fun onCreate(
savedInstanceState: Bundle?
) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.main_content)
) { view, insets ->
val systemBars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
)
view.setPadding(
systemBars.left,
systemBars.top,
systemBars.right,
systemBars.bottom
)
ViewCompat.ON_APPLY_WINDOW_INSETS_LISTENER
}
}
}
Σε αυτό το παράδειγμα το WindowInsets επιστρέφει αποστάσεις για όλες τις γραμμές συστήματος — Status Bar πάνω, Navigation Bar κάτω. Το setOnApplyWindowInsetsListener καλείται κάθε φορά που αλλάζουν τα insets (περιστροφή, κλήση πληκτρολογίου). Η μέθοδος systemBars() συνδυάζει τη γραμμή κατάστασης, γραμμή πλοήγησης και γραμμή προσαρμογής σε ένα σύνολο, απλοποιώντας τον κώδικα.
Από το Android 15, η Google απαιτεί edge-to-edge εμφάνιση για όλες τις εφαρμογές που στοχεύουν το νέο API. Αυτό σημαίνει ότι η εφαρμογή σχεδιάζεται κάτω από τις γραμμές συστήματος και το Safe Area εφαρμόζεται μέσω handleWindowInsets ή WindowInsetController. Σύμφωνα με το Android Developer Blog (2025), το 68% των εφαρμογών έχουν ήδη μεταβεί σε edge-to-edge, βελτιώνοντας την οπτική αντίληψη σε συσκευές με μεγάλες οθόνες.
Safe Area, Padding και Insets — συναφείς αλλά διαφορετικές έννοιες. Το Safe Area είναι η περιοχή οθόνης που είναι εγγυημένα ελεύθερη από στοιχεία συστήματος. Το Padding είναι η εσωτερική απόσταση ενός στοιχείου από τα όριά του. Τα Insets είναι οι συγκεκριμένες αριθμητικές τιμές αποστάσεων που επιστρέφονται από το API Safe Area. Σύμφωνα με το Apple Tech Notes (2025), η σύγχυση μεταξύ Safe Area και Padding είναι η αιτία του 40% των προβλημάτων προσαρμοστικότητας στα καταστήματα εφαρμογών.
| Έννοια | Ορισμός | Πλατφόρμα | Μεταβλητότητα |
|---|---|---|---|
| Safe Area | Περιοχή χωρίς στοιχεία συστήματος | iOS, Android | Δυναμική |
| Padding | Εσωτερική απόσταση εντός view | Όλες οι πλατφόρμες | Στατική |
| Layout Margins | Απόσταση από άκρα διάταξης | iOS (UIKit) | Στατική/δυναμική |
| WindowInsets | Αποστάσεις συστήματος Android | Android | Δυναμική |
Ας εξετάσουμε τυπικά σενάρια: Safe Area στο UIKit για οριζόντιο προσανατολισμό με notch, Safe Area στο SwiftUI με προσαρμοσμένο πλαίσιο, Safe Area στο Android Compose. Παράδειγμα για iOS UIKit — τοποθέτηση συλλογής εντός Safe Area σε iPhone με Dynamic Island. Παράδειγμα για Jetpack Compose — χρήση WindowInsets στο Material 3.
// Jetpack Compose: αποστάσεις από Safe Area
@OptIn(ExperimentalMaterial3Api::class)
fun SafeAreaScreen() {
val systemBars = with(
LocalDensity.current
) {
val insets = WindowInsets
.systemBars
.getAsPaddingValues()
PaddingValues(
top = insets.calculateTopPadding(),
bottom = insets.calculateBottomPadding()
)
}
Scaffold(
contentWindowInsets = WindowInsets(
top = systemBars.computeTopPadding(),
bottom = systemBars.computeBottomPadding()
)
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
) {
Text("Περιεχόμενο στο Safe Area")
}
}
}
Στο Jetpack Compose το Scaffold λαμβάνει αυτόματα υπόψη το WindowInsets μέσω της παραμέτρου contentWindowInsets. Το InnerPadding μεταβιβάζεται στο content και εφαρμόζεται σε εσωτερικά στοιχεία. Το Column με τροποποιητή padding(innerPadding) εγγυάται ότι το κείμενο δεν θα πέσει κάτω από τις γραμμές συστήματος.
Σύμφωνα με ανάλυση του App Store Review από την Apple (2025), πέντε πιο συνηθισμένα λάθη: αγνόηση του Safe Area σε οριζόντιο προσανατολισμό, χρήση σκληρά κωδικοποιημένων αποστάσεων αντί για SafeAreaLayoutGuide, εσφαλμένη επεξεργασία Safe Area σε UIScrollView, ξεχασμένες αποστάσεις σε modal παρουσιάσεις και έλλειψη προσαρμογής για Dynamic Island. Σκληρά κωδικοποιημένες αποστάσεις (hardcoded 20px πάνω) — το πιο συνηθισμένο λάθος: σε iPhone 14 Pro αυτά τα 20px μετατρέπονται σε 59px και το περιεχόμενο κόβεται.
Συχνές Ερωτήσεις
Στο SwiftUI το Safe Area εφαρμόζεται αυτόματα στους περισσότερους περιέκτες. Για ανάγνωση αποστάσεων χρησιμοποιήστε EnvironmentValues: @Environment(.safeAreaInsets) var safeAreaInsets. Για προσαρμοσμένα πλαίσια χρησιμοποιήστε .safeAreaInset(edge:content:). Για φόντο που πρέπει να εκτείνεται κάτω από στοιχεία συστήματος, εφαρμόστε .ignoresSafeArea().
Edge-to-edge — λειτουργία εμφάνισης όπου η εφαρμογή σχεδιάζεται κάτω από τις γραμμές συστήματος (Status Bar, Navigation Bar) και το Safe Area εφαρμόζεται μέσω WindowInsets. Από το Android 15, η Google απαιτεί edge-to-edge για όλες τις εφαρμογές με targetSdk 35. Υλοποιείται μέσω WindowInsetsCompat ή handleWindowInsets στο Jetpack Compose.
Ναι, το WebView πρέπει επίσης να λαμβάνει υπόψη το Safe Area. Στο iOS χρησιμοποιήστε webView.scrollView.contentInsetAdjustmentBehavior = .always. Στο Android προσθέστε android:fitsSystemWindows="true" στο XML ή προγραμματιστικό padding μέσω ViewCompat.setOnApplyWindowInsetsListener. Το περιβάλλον CSS (env(safe-area-inset-top)) λειτουργεί στο Safari, αλλά όχι στα WebView συστήματος Android.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης