팀에서 나의 역할을 하단 네비게이션 UI 작업을 하는 것이었다.
나는 공식 문서를 보며 Tab.Navigator
와 Tab.Screen
의 props를 활용하여 다음과 같이 코드를 짰다.
<Tab.Navigator
initialRouteName="Main_Map_Stack"
screenOptions={{
tabBarActiveTintColor: themeColor.mainColorFirst,
tabBarInactiveTintColor: themeColor.gray300,
tabBarLabelPosition: "beside-icon",
headerShown: false,
}}>
<Tab.Screen
name="Main_Map_Stack"
component={Main_Map_Stack}
options={{
tabBarLabel: '이벤트',
tabBarIcon: ({focused, color, size}) => (
<Icon name={focused? "calendar-check" : "calendar-heart"} color={color} size={size} />
),
}}
/>
<Tab.Screen
name="My_Like_Stack"
component={My_Like_Stack}
options={{
tabBarLabel: '찜 목록',
tabBarIcon: ({focused, color, size}) => (
<Icon name={focused? "cards-heart": "cards-heart-outline"} color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Profile_Stack"
component={Profile_Stack}
options={{
tabBarLabel: '프로필',
tabBarIcon: ({ focused, color, size}) => (
<Icon name={focused? "account":"account-outline"} color={color} size={size} />
),
}}
/>
</Tab.Navigator>
ℹ️ 참고: react-native-vector-icons 관련 문서
그런데 문제가 있었다.
Figma 문서에서는 '이벤트' 탭이 focused일 때의 아이콘은 다음과 같이 하트가 그려진 아이콘이었다.
그런데 react-native-vector-icons 아이콘 종류 모음에서 아무리 찾아봐도 똑같은 아이콘을 찾을 수 없었다.
그래서 우선 다음과 같이 체크 표시가된 아이콘으로 대체하고, 팀원들에게 이 아이콘을 쓸 수 있도록 허락을 구했다.
그러나 내가 임의로 넣은 아이콘은 다른 탭 아이콘의 디자인과 통일되지 않기 때문에 기각되었다.
하단 네비게이션을 다 작업하고 나서야 팀원들이 기존에 만들어 놓은 custom tab bar가 눈에 띄었다.
이미 내가 하단 네비게이션의 UI 작업을 완료했으니, 기존의 custom tab bar는 필요 없으리라 생각했는데, 확인해보니 아니었다.
custom tab bar에는 recoil을 사용하여 로그인 상태관리가 되어있는 상태였다.
즉, 나는 애초에 이 custom tab bar를 활용하여 하단 네비게이션 작업을 해야했던 것이었다.
시간이 많이 남아있으니, 나는 공식 문서를 보며, 내가 만들어 놓은 것을 custom tab bar로 옮기는 작업을 진행했다.
그런데 여기서 진짜 문제가 발생한다.
Bottom Tabs Navigator에서 custom tab bar 사용 시 icon 넣는 방법에 관한 자료를 아무리 찾아봐도 찾을 수 없었다.....
1) Figma에서 해당 아이콘을 export 한다.
추후에 아이콘의 컬러가 변경될 수도 있으니, SVG로 export했다.
2) React Native에서의 svg 이미지 사용법을 익힌다.
나의 포스팅인 [React Native] SVG 이미지 불러오는 방법를 보면 상세히 알 수 있다.
아무리 자료를 찾아봐도 없었기에, 공식 문서의 샘플 코드를 응용해보기로 했다.
샘플 코드에서는 options의 tabBarLabel
값을 불러올 수 있으니,tabBarIcon
의 값도 불러올 수 있을 것이라 생각했다.
그리고 (당연하게도) 내 예상은 맞았다.
<Tab.Screen
name="Main_Map_Stack"
component={Main_Map_Stack}
options={{
tabBarLabel: '이벤트',
tabBarIcon: ({focused, color, size}) => (
focused ?
<CalendarSvg width={20} height={22}/>
: <Icon name="calendar-heart" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="My_Like_Stack"
component={My_Like_Stack}
options={{
tabBarLabel: '찜 목록',
tabBarIcon: ({focused, color, size}) => (
<Icon name={focused? "cards-heart": "cards-heart-outline"} color={color} size={size} />
),
}}
/>
//options에 있는 tabBarIcon의 값을 가져옫다.
const tabIcon = options.tabBarIcon;
//...(생략)
///tabIcon을 삽입해준다.
{tabIcon({focused: isFocused, color: isFocused ? themeColor.black : themeColor.gray300, size: 24})}
하단 네비게이션을 작업하면서 최근에 읽은 <크리에이티브 프로그래머>의 내용이 떠올랐다.
이전에는 나는 '그린필드'라 불리는 '개인' 프로젝트만 해왔다.
개발을 하다가 문제를 마주치면, 자유롭게 회피할 수 있다.
마치 내가 하트가 그려진 달력 아이콘이 없다고 체크가 그려진 아이콘으로 대체한 것처럼.
그러나 지금 내가 하고 있는 건 팀 프로젝트, '브라운필드'라 불리는 프로젝트이다.
문제에 마주치더라도 멋대로 도망갈 수 없다.
팀원들과 정해 놓은 '약속'이 있기 때문이다.
이런 압박감이 있으니, 문제 해결할 수 있는 방법이 떠오르게 되었다.
이런 제약이 있으니, 실력이 한 단계 더 늘 수 있었다.
만약 이게 개인 프로젝트였다면, 이런 기분을 느낄 수 있었을까?
'나는 문제를 어떻게든 해결할 수 있다'는 기분 말이다.