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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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