Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Безопасная зона экрана

У современных телефонов экран занимает всю переднюю панель: сверху вырез камеры и строка состояния с часами, снизу полоска жестов. Безопасная зона (safe area) — часть экрана, которую ничто не закрывает. Содержимое, особенно текст и кнопки, должно находиться в ней.

Когда это нужно

Шапка стека и панель вкладок Expo Router сами учитывают безопасную зону. Проблема появляется на экранах без шапки. Скройте шапку в списке задач:

// app/_layout.tsx
import { Stack } from 'expo-router';
 
export default function RootLayout() {
  return <Stack screenOptions={{ headerShown: false }} />;
}

Теперь заголовок «Мои задачи» на iPhone окажется под часами и вырезом камеры, а на Android — под строкой состояния.

SafeAreaView

Компонент SafeAreaView из пакета react-native-safe-area-context добавляет отступы ровно по размеру системных элементов. Пакет уже установлен в шаблоне Expo.

// app/index.tsx
import { Text } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
 
export default function Index() {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
      <Text style={{ fontSize: 24, padding: 16 }}>Мои задачи</Text>
    </SafeAreaView>
  );
}

Заголовок опустится ниже часов и выреза. Белый фон при этом заполнит экран целиком, включая область под строкой состояния, — отступ добавляется внутрь.

Проп edges выбирает стороны: edges={['top']} добавит отступ только сверху. Это нужно, если снизу экрана находится панель вкладок, которая уже учитывает нижнюю зону.

useSafeAreaInsets

Хук возвращает размеры отступов числами — их можно использовать в любом стиле. Например, прижать кнопку «Добавить» к низу экрана над полоской жестов:

// app/index.tsx
import { View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import AppButton from '@/components/AppButton';
 
export default function Index() {
  const insets = useSafeAreaInsets();
 
  return (
    <View style={{ flex: 1, paddingTop: insets.top, paddingBottom: insets.bottom + 8 }}>
      <View style={{ flex: 1 }} />
      <AppButton title="Добавить задачу" onPress={() => {}} />
    </View>
  );
}

insets содержит четыре числа: top, bottom, left, right. На iPhone с вырезом top около 50–60, на старых телефонах с кнопкой «Домой» — около 20.

Провайдер

Компоненты безопасной зоны работают внутри SafeAreaProvider. Expo Router добавляет его сам, поэтому в проектах с Expo Router оборачивать приложение вручную не нужно.

Частая ошибка

Импортировать SafeAreaView из react-native. Этот старый компонент работает только на iOS, на Android ничего не делает и в React Native 0.81 объявлен устаревшим. Импортируйте SafeAreaView из react-native-safe-area-context.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.