React Native

React Navigtion의 Header 커스텀하기

Beekei 2022. 2. 11. 23:45
반응형

헤더 타이틀 커스터마이징

react-navigation에서는 타이틀 영역을 헤더(Header)라고 부른다.

헤더 부분의 타이틀을 커스터마이징할 땐 두 가지 방법이 있는데, 첫 번째 방법은 Stack.Screen의 options 속성으로 설정하는 것이다.

<Stack.Screen
  name="Home"
  component={HoemScreen}
  options={{
    title: '홈',
  }}
/>

두 번째 방법은 화면 컴포넌트에서 navigation.setOptions 함수를 사용하는 것이다.

아래 예제는 useEffect Hook 함수를 사용하였다.

function HomeScreen({navigation}) {

  useEffect(() => {
    navigation.setOptions({title: '홈'});
  }, [navigation]);

  return ( ... );

}

좌측 options 설정 전 / 우측 options 설정 후

만약 컴포넌트에 라우트 파라미터값을 넣어야 한다면 아래와 같이 함수로 설정해야 한다.

<Stack.Screen
  name="Detail"
  component={DetailScreen}
  options={route => ({
    title: `상세정보 - ${route.params.id}`,
  })}
/>

아래 코드는 위에서 설명한 두 번째 방법이다.

function DetailScreen({navigation, route}) {

  useEffect(() => {
    navigation.setOptions({title: `상세 정보 - ${route.params.id}`});
  }, [navigation, route.params.id]);

  return ( ... );

}

 

헤더 스타일 변경하기

헤더의 스타일도 세부적으로 커스터마이징할 수 있다. 

<Stack.Screen
  name="Home"
  component={HoemScreen}
  options={{
    title: '홈',
    // Header 블록에 대한 스타일
    headerStyle: { 
      backgroundColor: '#29b6f6',
    },
    // Header의 텍스트, 버튼 색상
    headerTintColor: '#ffffff',
    // 타이틀 텍스트의 스타일
    headerTitleStyle: {
      fontWeight: 'bold',
      fontSize: 20,
    },
  }}
/>

 

헤더의 좌측, 타이틀, 우측 영역에 다른 컴포넌트 보여주기

헤더의 좌측(뒤로가기) 영역, 중앙(타이틀) 영역, 우측 영역을 각 다른 컴포넌트로 보여줄 수 있다.

<Stack.Screen
  name="Detail"
  component={DetailScreen}
  options={{
    headerLeft: ({onPress}) => (
      <TouchableOpacity onPress={onPress}>
        <Text>Left</Text>
      </TouchableOpacity>
    ),
    headerTitle: ({children}) => (
      <View>
        <Text>{children}</Text>
      </View>
    ),
    headerRight: () => (
      <View>
        <Text>Right</Text>
      </View>
    ),
  }}
/>

headerLeft, headerTitle, headerRight에 함수 컴포넌트를 넣어 헤더 내부 영역에 보여줄 컴포넌트를 직접 설정할 수 있다. 여기서 headerTitle에 넣은 컴포넌트를 보면 children이라는 Props를 받아오고 있다. 현재 이 값은 화면이 타이틀을 가리킨다.

좌측 iOS / 우측 안드로이드

안드로이드에서 확인해보면 뒤로가기 화살표가 나타나는 것을 확인할 수 있다. 만약 이 버튼을 없애고 싶다면, headerBackVisible 옵션을 false로 설정하면 된다.

<Stack.Screen
  name="Detail"
  component={DetailScreen}
  options={{
    headerBackVisible: false,
    headerLeft: ({onPress}) => (
      <TouchableOpacity onPress={onPress}>
        <Text>Left</Text>
      </TouchableOpacity>
    ),
    headerTitle: ({children}) => (
      <View>
        <Text>{children}</Text>
      </View>
    ),
    headerRight: () => (
      <View>
        <Text>Right</Text>
      </View>
    ),
  }}
/>

 

헤더 숨기기

헤더를 숨길때는 Stack.Screen headerShown 옵션을 false로 설정하면 된다.

<Stack.Screen
  name="Headerless"
  component={HeaderlessScreen}
  options={{headerShown: false}}
/>

좌측 iOS / 우측 안드로이드

옵션을 설정하고 확인해 보면 안드로이드는 정상적으로 작동하지만 iOS는 StatusBar 영역을 침범해서 화면이 나타나고 있다.

이럴땐 SafeAreaVIew 컴포넌트로 해당 컴포넌트를 감싸야 한다.

import React from 'react';
import {View, Text, Button} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';

function HeaderlessScreen({navigation}) {
  return (
    <SafeAreaView>
      <View>
        <Text>Header가 없네?</Text>
        <Button onPress={() => navigation.pop()} title="뒤로기기" />
      </View>
    </SafeAreaView>
  );
}

export default HeaderlessScreen;

 

만약 헤더와 관련한 설정을 특정 화면에서만 적용하지 않고, 네이티브 스택 내비게이터에서 관리하는 모든 화면에 넣고 싶다면 Stack.Navigator에 screenOptions라는 Props를 설정하면 된다. 이 Props에 넣은 값은 Stack.Screen의 options와 같다.

<Stack.Navigator
  initialRouteName="Home"
  screenOptions={{
    headerShown: false,
  }}
>
...

 

더 자세한 내용은 공식 문서를 참고바란다.

 

https://reactnavigation.org/docs/native-stack-navigator/#options

 

reactnavigation.org

반응형