Safe Area — що це, відступи від notch та StatusBar

Автор: IT Sectr Опубліковано: 2026-02-25 Час читання: 8 хв

Показуємо, що таке Safe Area — безпечна зона екрану, яка гарантує, що контент не перекривається системними елементами: notch, Dynamic Island, StatusBar, індикатором Home та заокругленими кутами. Safe Area — обов'язковий елемент адаптивного верстання в iOS та Android, без якого інтерфейс може виглядати некоректно на пристроях з вирізами. За даними Apple HIG (2025), з моменту появи iPhone X у 2017 році всі застосунки зобов'язані використовувати Safe Area Layout Guide.

Головне

  • Safe Area — область екрану, вільна від системних елементів: notch, StatusBar, Home Indicator, заокруглених кутів.
  • У iOS Safe Area реалізовано через SafeAreaLayoutGuide та модифікатор .safeAreaInset() у SwiftUI.
  • В Android Safe Area реалізовано через WindowInsets та WindowInsetsCompat для підтримки старих версій.
  • Dynamic Island на iPhone 14 Pro та новіших замінює notch і також враховується в Safe Area.
  • За даними Google Android Docs (2025), ігнорування Safe Area — одна з трьох головних причин відхилення застосунків у Google Play та App Store.

Що таке Safe Area?

Safe Area — це прямокутна область екрану, в якій контент гарантовано не перекривається апаратними та програмними системними елементами: вирізом камери (notch), Dynamic Island, рядком стану (StatusBar), індикатором жестової навігації (Home Indicator), заокругленими кутами дисплея та панеллю навігації. Межі Safe Area динамічно змінюються при повороті пристрою, виклику клавіатури або запуску Split View. Згідно з Apple Human Interface Guidelines (2025), ігнорування Safe Area вважається помилкою дизайну і може призвести до відхилення застосунку під час рев'ю.

Навіщо потрібна Safe Area

Safe Area вирішує проблему фрагментації екранів у мобільній екосистемі. До iPhone X всі iPhone мали прямокутний дисплей з однаковими пропорціями. З появою notch кількість варіантів екранів зросла до 20+ — різні розміри ноутчів, Dynamic Island, заокруглення, індикатори. Safe Area абстрагує розробника від цих відмінностей, надаючи єдиний API для адаптивних відступів. За даними Apple Developer (2025), iOS автоматично застосовує Safe Area для кореневого view, але для UICollectionView та UIScrollView потрібне ручне налаштування.

ПристрійТип вирізуВерхній відступНижній відступStatusBar
iPhone SE (3rd gen)Немає20px0pxЄ
iPhone 13 ProNotch47px34pxВсередині notch
iPhone 14 ProDynamic Island59px34pxВсередині DI
iPhone 16 ProDynamic Island59px34pxВсередині DI
Android Pixel 8Punch-hole (камера)24px24pxСтатус бар

Safe Area в iOS: SafeAreaLayoutGuide та SwiftUI

У iOS Safe Area реалізовано через SafeAreaLayoutGuide в UIKit та модифікатор safeAreaInset в SwiftUI. SafeAreaLayoutGuide — це layout guide, який додається до кожного UIView та визначає прямокутник, вільний від системних елементів. В Interface Builder Safe Area відображається у вигляді блакитної області. SwiftUI застосовує Safe Area автоматично для більшості контейнерів, але дозволяє ігнорувати її через .ignoresSafeArea().

Swift
// 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.

Swift
// 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 з вказаної сторони. Це стандартний патерн для навігаційних панелей, тулбарів та рекламних банерів.

Safe Area в Android: WindowInsets та System Bars

В Android Safe Area реалізовано через WindowInsets (API 30+) та WindowInsetsCompat (бібліотека AndroidX). WindowInsets надає відступи для Status Bar, Navigation Bar, IME (клавіатура) та системних жестів. Починаючи з Android 10 (API 29), Google рекомендує використовувати WindowInsetsCompat.getInsets() з типом WindowInsetsCompat.Type.systemBars() для отримання єдиного набору відступів під всі системні елементи.

Kotlin
// 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() об'єднує статус бар, навігаційний бар та бар кастомізації в один набір, що спрощує код.

Edge-to-Edge в Android

Починаючи з 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 — це область екрану, гарантовано вільна від системних елементів. Padding — внутрішній відступ елемента від його меж. Insets — конкретні числові значення відступів, які повертає API Safe Area. За даними Apple Tech Notes (2025), плутанина між Safe Area та Padding — причина 40% проблем з адаптивністю в сторах застосунків.

ПоняттяВизначенняПлатформаЗмінюваність
Safe AreaОбласть без системних елементівiOS, AndroidДинамічна
PaddingВнутрішній відступ всередині viewВсі платформиСтатична
Layout MarginsВідступ від країв layoutiOS (UIKit)Статична/динамічна
WindowInsetsСистемні відступи AndroidAndroidДинамічна

Приклади реалізації Safe Area з кодом

Розглянемо типові сценарії: Safe Area в UIKit для горизонтальної орієнтації з notch, Safe Area в SwiftUI з кастомною панеллю, Safe Area в Android Compose. Приклад для iOS UIKit — розміщення колекції всередині Safe Area на iPhone з Dynamic Island. Приклад для Jetpack Compose — використання WindowInsets в Material 3.

Kotlin
// 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) гарантує, що текст не потрапить під системні бари.

Типові помилки при роботі з Safe Area

За даними аналізу App Store Review від Apple (2025), п'ять найчастіших помилок: ігнорування Safe Area в ландшафтній орієнтації, використання жорстко заданих відступів замість SafeAreaLayoutGuide, неправильна обробка Safe Area в UIScrollView, забуті відступи в модальних презентаціях та відсутність адаптації для Dynamic Island. Жорсткі відступи (hardcoded 20px зверху) — найпоширеніша помилка: на iPhone 14 Pro ці 20px перетворюються на 59px, і контент обрізається.

  • Ігнорування ландшафту — в горизонтальній орієнтації Safe Area має інші відступи: Home Indicator зміщується на праву сторону, а верхній відступ зменшується.
  • Hardcoded відступи — цифри 20px або 44px підходять тільки для старих iPhone без ноуча. На сучасних пристроях відступи відрізняються в 2-3 рази.
  • ScrollView та Safe Area — contentInsetAdjustmentBehavior в UIScrollView потрібно налаштувати на .always, інакше контент буде приховано під системними барами.

Часто задавані питання

Як отримати Safe Area відступи в SwiftUI?

В SwiftUI Safe Area застосовується автоматично до більшості контейнерів. Для читання відступів використовуйте EnvironmentValues: @Environment(\.safeAreaInsets) var safeAreaInsets. Для кастомних панелей використовуйте .safeAreaInset(edge:content:). Для фону, який повинен розтягнутися під системні елементи, застосуйте .ignoresSafeArea().

Що таке edge-to-edge в Android?

Edge-to-edge — режим відображення, при якому застосунок малюється під системними барами (Status Bar, Navigation Bar), а Safe Area застосовується через WindowInsets. Починаючи з Android 15, Google вимагає edge-to-edge для всіх застосунків з targetSdk 35. Реалізується через WindowInsetsCompat або handleWindowInsets в Jetpack Compose.

Чи потрібно обробляти Safe Area для WebView?

Так, WebView також повинен враховувати Safe Area. В iOS використовуйте webView.scrollView.contentInsetAdjustmentBehavior = .always. В Android додайте android:fitsSystemWindows="true" в XML або programmatic padding через ViewCompat.setOnApplyWindowInsetsListener. CSS-оточення (env(safe-area-inset-top)) працює в Safari, але не в системних WebView Android.

Підсумки

  • Safe Area — область екрану, вільна від notch, Dynamic Island, StatusBar та Home Indicator.
  • iOS: реалізована через SafeAreaLayoutGuide в UIKit та .safeAreaInset в SwiftUI.
  • Android: реалізована через WindowInsets (API 30+) або WindowInsetsCompat (AndroidX).
  • Dynamic Island на iPhone 14 Pro та новіших збільшує верхній відступ Safe Area до 59px.
  • Ігнорування Safe Area — одна з головних причин відхилення застосунків в App Store та Google Play.
  • Жорсткі відступи неприпустимі — завжди використовуйте програмні API Safe Area.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також