React Native - Top Tab Navigation

MIMO·2023년 8월 23일
0

Frontend

목록 보기
3/4

프로젝트를 진행하던 와중에 가장 위쪽에 Tab을 두어야 할 일이 생겼다.

본래는 해당 UI를 직접 구현하려 하였지만, appStack으로 구현을 해버리면 페이지가 넘어갈 때 마다 이전 페이지 위에 덮어쓰는 식으로 stack이 쌓였다. 그렇기 때문에 라이브러리를 하나 찾아 주었다.

프로젝트를 진행하면서 사용한 Navigation은 아래와 같다. (많이도 썼다)

각각이 어떤 Navigation인지는 React Navigation에 가면 자세히 나와있다. 구조만 간략히 말하면 RootNavigator에서 Token이 있는지를 검사하고 Token이 있다면 appStack으로, Token이 없다면 AuthStack으로 넘긴다. appStack으로 넘어오면 가장 먼저 반기는 Page가 바로 ClientTabs이다. 이름을 저렇게 설정해 주었지만, 하단 네비게이션이다.

위처럼 세팅되어 있는 Navigation에 상단 탭을 추가하려 한다. 모든 페이지에서 사용할 것은 아니기 때문에 파일을 추가하여 정의해준 뒤, appStack에서 정의한 후 원하는 진입점에서 Routing 시키면 될 것이다.

Materials Top Tab

좀 빨리 찾았더라면 고생을 덜 할 수 있었을 텐데.. 라는 아쉬움이 남지만 하나 알아간다는 생각에 아쉬움을 접어 두자

https://reactnavigation.org/docs/material-top-tab-navigator/

위 사이트에서 사용방법이 자세히 나와있다. 하지만 나는 특정 페이지에서만 Top Tab을 불러주어야 하기 때문에 Custom이 좀 필요했다.

const Tab = createMaterialTopTabNavigator();
export default function TopBarNavigation() {

  return (
    <><Header title={'스위트룸'} backScreen='Mystudy' />
    <Tab.Navigator
          initialRouteName="SuiteRoomDashboard"
          screenOptions={{
              tabBarActiveTintColor: '#050953',
              tabBarLabelStyle: { fontSize: 14, color : '#050953' },
              tabBarStyle: { backgroundColor: 'white' },
          }}
      >
          <Tab.Screen
              name="대시보드"
              component={SuiteRoomDashboard}
              options={{ tabBarLabel: '대시보드' }} />
          <Tab.Screen
              name="칸반보드"
              component={SuiteRoomCanbanBoard}
              options={{ tabBarLabel: '칸반보드' }} />
          <Tab.Screen
              name="내출석부"
              component={SuiteRoomMyAttendance}
              options={{ tabBarLabel: '내출석부' }} />
            <Tab.Screen
              name="스위트룸"
              component={SuiteRoomDetailStart}
              options={{ tabBarLabel: '스위트룸' }} />
      </Tab.Navigator></>
  );
}

우선 위와 같이 Top Tab을 작성해둔다.

<App.Screen
        name="TabBarNavigation"
        component={TabBarNavigation} 
        options={{
          headerShown: false,
        }}
/>

하던 대로 appStack에 TabBarNavigation을 추가해준다. 그 다음에서 좀 애를 먹었는데, Top Bar가 달린 페이지로 바로 이동시키는 것이 아니라, Top Bar를 설정한 TabBarNavigation으로 이동시켜주어야 한다.

onPress={() => {
  navigation.navigate('TabBarNavigation');
}}>

위와 같이 말이다. 그럼 성공적으로 원하는 화면을 볼 수 있을 것이다.

Top Bar Navigation Props

이후 사용할 일이 좀 있을 것 같아서 Props들을 정리해둔다. 다 공식 메뉴얼에 있는 내용들이다.

  • initialRouteName : 초기 화면의 이름
  • screenOptions : 화면의 기본 설정, 하단 탭 내비게이션과 비슷한데, 다음과 같은 추가 옵션이 있다.
  • swipeEnabled : 화면을 좌우로 스와이프하여 전환 설정(default : true)
  • lazy : 특정 탭으로 이동해야만 해당 탭을 렌더링 하도록 설정
  • lazyPreloadDistance : lazy 속성이 활성화된 상태에서 몇 칸 뒤 화면을 미리 불러올지 설정(default : 0)
  • lazyPlaceholder : lazy 속성이 활성화되어 있을 때 아직 보이지 않은 화면에서 보여줄 대체 컴포넌트
  • tabBarIndicator : 활성화된 탭을 표시하는 컴포넌트
  • tabBarIndicatorStyle : 활성화된 탭을 표시하는 컴포넌트의 스타일
  • backBehavior : 뒤로가기할 때의 작동 방식
  • tabBarPosition : 탭 바의 위치(top 또는 bottom)
  • keyboardDismissMode : 키보드를 숨기는 설정
    - auto : 기본값. 화면이 바뀔 때 키보드를 숨김
    - on-drag : 화면을 드래그할 때 키보드를 숨김
    - none : 드래그해도 키보드를 숨기지 않는다.
  • sceneContainerStyle : 각 화며에 대한 스타일
  • style : 전체 캡 뷰에 대한 스타일
  • tabBar : 탭 바를 대체할 수 있는 컴포넌트

다른 props들은 사용하면 될 것 같은데 ScreenOptions을 찾아서 사용하는게 좀 어려웠다. 사실 공식문서 해석했으면 5분도 안걸렸을것 같은데 괜히 혼자 박치기 하느라 오래 걸렸다.

screenOptions 커스텀

프로젝트에는 누르지 않은 버튼은 회색으로 보이고, 눌렀을 경우에만 색깔을 입히고 싶었다.

screenOptions={{
      tabBarActiveTintColor: '#050953',
      tabBarInactiveTintColor : '#B8B8B8',
      tabBarLabelStyle: { fontSize: 14, fontWeight : 'bold' },
      tabBarStyle: { backgroundColor: 'white' },
}}
  • tabBarActiveTintColor : 눌렀을 때의 Icon과 Label의 색깔을 정한다.
  • tabBarInActiveTintColor : 눌러지지 않았을 때의 Icon과 Label의 색깔을 정한다.
  • tabBarLabelStyle : Label의 Style을 지정한다. 여기서 색깔을 정해 버리면 위 props들과 상관없이 색깔이 정해지기 때문에 잘 설정해주어야 한다.
  • tabBarStyle : tabBar의 Style을 지정해줄 수 있다.

위와 같이 설정해주면 아래 사진과 같은 top tap navigation을 얻을 수 있다.

profile
행복한 사람

0개의 댓글