Ukazujeme, co je Safe Area — bezpečná zóna obrazovky, která zaručuje, že obsah není překryt systémovými prvky: notch, Dynamic Island, StatusBar, indikátorem Home a zaoblenými rohy. Safe Area je povinný prvek adaptivního rozvržení v iOS a Android, bez kterého může rozhraní vypadat nesprávně na zařízeních s výřezy. Podle Apple HIG (2025) jsou od uvedení iPhone X v roce 2017 všechny aplikace povinny používat Safe Area Layout Guide.
Hlavní body
Safe Area — je obdélníková oblast obrazovky, ve které obsah není zaručeně překryt hardwarovými a softwarovými systémovými prvky: výřezem kamery (notch), Dynamic Island, stavovým řádkem (StatusBar), indikátorem gestové navigace (Home Indicator), zaoblenými rohy displeje a navigačním panelem. Hranice Safe Area se dynamicky mění při otočení zařízení, vyvolání klávesnice nebo spuštění Split View. Podle Apple Human Interface Guidelines (2025) je ignorování Safe Area považováno za chybu designu a může vést k zamítnutí aplikace při revizi.
Safe Area řeší problém fragmentace obrazovek v mobilním ekosystému. Před iPhone X měly všechny iPhone obdélníkový displej se stejnými proporcemi. S příchodem notch vzrostl počet variant obrazovek na 20+ — různé velikosti výřezů, Dynamic Island, zaoblení, indikátory. Safe Area abstrahuje vývojáře od těchto rozdílů a poskytuje jednotné API pro adaptivní odsazení. Podle Apple Developer (2025) iOS automaticky aplikuje Safe Area pro kořenové zobrazení, ale pro UICollectionView a UIScrollView je vyžadována ruční konfigurace.
| Zařízení | Typ výřezu | Horní odsazení | Dolní odsazení | StatusBar |
|---|---|---|---|---|
| iPhone SE (3rd gen) | Žádný | 20px | 0px | Ano |
| iPhone 13 Pro | Notch | 47px | 34px | Uvnitř notch |
| iPhone 14 Pro | Dynamic Island | 59px | 34px | Uvnitř DI |
| iPhone 16 Pro | Dynamic Island | 59px | 34px | Uvnitř DI |
| Android Pixel 8 | Punch-hole (kamera) | 24px | 24px | Stavový řádek |
V iOS je Safe Area implementována přes SafeAreaLayoutGuide v UIKit a modifikátor safeAreaInset ve SwiftUI. SafeAreaLayoutGuide je průvodce rozvržením, který je přidán ke každému UIView a definuje obdélník bez systémových prvků. V Interface Builder je Safe Area zobrazena jako modrá oblast. SwiftUI aplikuje Safe Area automaticky pro většinu kontejnerů, ale umožňuje ji ignorovat přes .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 v UIKit definuje čtyři anchor — top, bottom, leading, trailing — které automaticky zohledňují notch, StatusBar a Home Indicator. Tento přístup funguje na všech iOS zařízeních od iOS 11. Ve SwiftUI je stejného efektu dosaženo modifikátorem obsahu uvnitř NavigationStack nebo VStack — SwiftUI automaticky aplikuje Safe Area Insets.
// SwiftUI: safeAreaInset a ignoresSafeArea
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
Text("Obsah v Safe Area")
.foregroundColor(.white)
Spacer()
}
}
.safeAreaInset(edge: .bottom) {
Text("Lišta dole na obrazovce")
.padding()
.background(.thinMaterial)
}
Ve SwiftUI .ignoresSafeArea() umožňuje pozadí rozšířit se za Safe Area a .safeAreaInset(edge:) přidá vlastní panel, který zmenšuje Safe Area z uvedené strany. Toto je standardní vzor pro navigační panely, nástrojové lišty a reklamní bannery.
V Android je Safe Area implementována přes WindowInsets (API 30+) a WindowInsetsCompat (knihovna AndroidX). WindowInsets poskytuje odsazení pro Status Bar, Navigation Bar, IME (klávesnice) a systémová gesta. Od Android 10 (API 29) Google doporučuje používat WindowInsetsCompat.getInsets() s typem WindowInsetsCompat.Type.systemBars() pro získání jednotné sady odsazení pro všechny systémové prvky.
// 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
}
}
}
V tomto příkladu WindowInsets vrací odsazení pro všechny systémové lišty — Status Bar nahoře, Navigation Bar dole. setOnApplyWindowInsetsListener je volán pokaždé, když se insets změní (otočení, vyvolání klávesnice). Metoda systemBars() kombinuje stavový řádek, navigační lištu a lištu přizpůsobení do jedné sady, což zjednodušuje kód.
Od Android 15 Google vyžaduje edge-to-edge zobrazení pro všechny aplikace cílící na nové API. To znamená, že aplikace je kreslena pod systémovými lištami a Safe Area je aplikována přes handleWindowInsets nebo WindowInsetController. Podle Android Developer Blog (2025) již 68% aplikací přešlo na edge-to-edge, což zlepšuje vizuální vnímání na zařízeních s velkými obrazovkami.
Safe Area, Padding a Insets — související, ale odlišné pojmy. Safe Area je oblast obrazovky zaručeně bez systémových prvků. Padding je vnitřní odsazení prvku od jeho hranic. Insets jsou konkrétní číselné hodnoty odsazení vrácené API Safe Area. Podle Apple Tech Notes (2025) je záměna Safe Area a Padding příčinou 40% problémů s adaptivitou v obchodech s aplikacemi.
| Pojem | Definice | Platforma | Proměnlivost |
|---|---|---|---|
| Safe Area | Oblast bez systémových prvků | iOS, Android | Dynamická |
| Padding | Vnitřní odsazení uvnitř view | Všechny platformy | Statická |
| Layout Margins | Odsazení od okrajů layout | iOS (UIKit) | Statická/dynamická |
| WindowInsets | Systémová odsazení Android | Android | Dynamická |
Podívejme se na typické scénáře: Safe Area v UIKit pro horizontální orientaci s notch, Safe Area ve SwiftUI s vlastním panelem, Safe Area v Android Compose. Příklad pro iOS UIKit — umístění kolekce uvnitř Safe Area na iPhone s Dynamic Island. Příklad pro Jetpack Compose — použití WindowInsets v Material 3.
// Jetpack Compose: odsazení od 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("Obsah v Safe Area")
}
}
}
V Jetpack Compose Scaffold automaticky zohledňuje WindowInsets přes parametr contentWindowInsets. InnerPadding je předán do content a aplikován na vnitřní prvky. Column s modifikátorem padding(innerPadding) zaručuje, že text nespadne pod systémové lišty.
Podle analýzy App Store Review od Apple (2025) je pět nejčastějších chyb: ignorování Safe Area v horizontální orientaci, používání pevně daných odsazení místo SafeAreaLayoutGuide, nesprávné zpracování Safe Area v UIScrollView, zapomenutá odsazení v modálních prezentacích a chybějící adaptace pro Dynamic Island. Pevně daná odsazení (hardcoded 20px nahoře) — nejčastější chyba: na iPhone 14 Pro se těchto 20px mění na 59px a obsah je oříznut.
Často kladené otázky
Ve SwiftUI je Safe Area aplikována automaticky na většinu kontejnerů. Pro čtení odsazení použijte EnvironmentValues: @Environment(.safeAreaInsets) var safeAreaInsets. Pro vlastní panely použijte .safeAreaInset(edge:content:). Pro pozadí, které se má rozšířit pod systémové prvky, aplikujte .ignoresSafeArea().
Edge-to-edge — režim zobrazení, při kterém je aplikace kreslena pod systémovými lištami (Status Bar, Navigation Bar) a Safe Area je aplikována přes WindowInsets. Od Android 15 Google vyžaduje edge-to-edge pro všechny aplikace s targetSdk 35. Implementuje se přes WindowInsetsCompat nebo handleWindowInsets v Jetpack Compose.
Ano, WebView musí také zohledňovat Safe Area. V iOS použijte webView.scrollView.contentInsetAdjustmentBehavior = .always. V Android přidejte android:fitsSystemWindows="true" do XML nebo programové padding přes ViewCompat.setOnApplyWindowInsetsListener. CSS prostředí (env(safe-area-inset-top)) funguje v Safari, ale ne v systémových WebView Android.
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é