Показујемо шта је 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 са наведене стране. Ово је стандардни образац за навигационе панеле, траке са алаткама и рекламне банере.
У 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 су конкретне нумеричке вредности одступања које враћа Safe Area API. Према Apple Tech Notes (2025), забуна између Safe Area и Padding-а је узрок 40% проблема са адаптивношћу у продавницама апликација.
| Концепт | Дефиниција | Платформа | Променљивост |
|---|---|---|---|
| Safe Area | Област без системских елемената | iOS, Android | Динамичка |
| Padding | Унутрашње одступање унутар view | Све платформе | Статичка |
| Layout Margins | Одступање од ивица layout | 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, заборављена одступања у модалним презентацијама и недостатак адаптације за 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође