[1인 개발] React Native와 Expo Router로 소셜 앱 만들기 (2) - UI 디테일 & 화면 구현

김승철·2025년 9월 9일
3

1인개발

목록 보기
2/3

안녕하세요! 소셜 커뮤니티 앱 '커넥트' 1인 개발자입니다.

지난 1편에서는 개발 환경 설정부터 홈 화면의 기본 뼈대를 잡는 과정까지 공유했는데요, 이번 2편에서는 Mock 데이터를 기반으로 완성된 UI를 사용자의 피드백을 반영하며 디테일을 다듬고, '게시글 작성'과 '운세/타로' 화면을 구현하는 과정을 기록해보려고 합니다.


UI 디테일 다듬기: 사소하지만 중요한 차이

기본적인 UI 구현을 마친 뒤, 실제 기기에서 앱을 실행해보니 몇 가지 아쉬운 점들이 눈에 띄었습니다. 사용성과 디자인 완성도를 높이기 위해 다음과 같은 부분들을 수정했습니다.

1. 헤더(Header) 스타일 커스터마이징

Expo Router의 기본 헤더는 편리하지만, 디자인에 맞게 높이를 조절하고 싶었습니다. app/(tabs)/_layout.tsx 파일에서 headerStyle 옵션을 사용해 높이를 직접 지정하고, 그림자 대신 얇은 경계선을 추가하여 더 깔끔한 느낌을 주었습니다.

<Tabs
  screenOptions={{
    // ...
    headerStyle: {
      backgroundColor: '#fff', 
      height: 70, // 헤더 높이를 직접 지정
      borderBottomWidth: 1, // 그림자 대신 경계선 추가
      borderBottomColor: '#f3f4f6',
    },
  }}>
  // ...
</Tabs>

2.Expo go 안드로이드 하단 바 겹침 문제 해결

Expo의 가장 큰 장점 중 하나는 바로 'Expo Go'라는 앱을 통해, 터미널에 뜨는 QR코드를 스캔하기만 하면 내 핸드폰에서 바로 앱을 확인해볼 수 있다는 점입니다.

안드로이드 기기에서 테스트하니, 하단의 탭 바가 시스템 내비게이션 바(홈, 뒤로가기 버튼)에 가려지는 현상이 발생했습니다. useSafeAreaInsets 훅을 사용해 간단하게 해결했습니다.

useSafeAreaInsets를 사용하면 시스템 UI가 차지하는 영역의 크기를 알 수 있습니다.
import { useSafeAreaInsets } from 'react-native-safe-area-context';

export default function TabLayout() {
const insets = useSafeAreaInsets(); // 기기의 안전 영역 값 가져오기

import { useSafeAreaInsets } from 'react-native-safe-area-context';

export default function TabLayout() {
  const insets = useSafeAreaInsets(); // 기기의 안전 영역 값 가져오기

  return (
    <Tabs
      screenOptions={{
        // ...
         tabBarStyle: {
          height: 60 + insets.bottom, // 기본 높이에 하단 여백 추가
          paddingBottom: insets.bottom, // 아이콘이 가려지지 않도록 패딩 추가
          // ...
        }
      }}>
      // ...
    </Tabs>
  );
}

3. SVG 로고 컴포넌트 제작 및 적용

헤더에 텍스트 대신 앱의 정체성을 보여주는 로고를 넣고 싶었습니다. 이미지 파일을 사용하는 대신, 어떤 해상도에서도 깨지지 않는 벡터 그래픽을 위해 react-native-svg 라이브러리를 설치하고, 텍스트 기반의 간단한 로고 컴포넌트를 만들었습니다.

import React from 'react';
import Svg, { Text, Defs, LinearGradient, Stop } from 'react-native-svg';

export function Logo() {
  // ... SVG 코드
}

이렇게 만든 로고를 _layout.tsx에서 headerLeft 옵션을 사용해 헤더 왼쪽에 배치했습니다.


핵심 화면 구현하기

1. 글쓰기 Modal 화면

Expo Router는 app 폴더 최상위에 파일을 만들면 탭 바가 없는 전체 화면으로 띄워줍니다. 이를 이용해 app/writePost.tsx 파일을 생성하고, app/_layout.tsx에서 presentation: 'modal' 옵션을 주어 아래에서 위로 올라오는 부드러운 애니메이션 효과를 적용했습니다.

import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack>
      {/* 기본 탭 화면들 */}
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      
      {/* 글쓰기 화면을 Modal로 설정 */}
      <Stack.Screen 
        name="writePost" 
        options={{ 
          presentation: 'modal', 
          headerShown: false, // 커스텀 헤더를 사용할 것이므로 기본 헤더는 숨김
        }} 
      />
    </Stack>
  );
}

2. 운세/타로 선택 화면

기획에 있던 운세/타로 기능을 위한 화면(fortune.tsx)도 구현했습니다. ImageBackground 컴포넌트를 사용해 각 메뉴 카드에 배경 이미지를 자연스럽게 입히고, 그 위에 그라데이션 오버레이와 텍스트를 배치하여 시각적인 완성도를 높였습니다.

각 운세 메뉴를 카드 형태로 구현한 모습


다음 목표: 나머지 화면 UI 완성

제가 잠시 너무 앞서나가 데이터 연동을 생각했지만, 아직은 UI를 완성하는 것이 우선이라는 생각이 들었습니다. 앱의 모든 기능이 어떤 모습일지 눈으로 먼저 확인하는 것이 중요하니까요.

따라서 다음 목표는 아직 비어있는 나머지 탭 화면들의 UI를 모두 구현하는 것입니다.

  • 채팅방 목록 화면 UI 구현
  • 마이페이지 UI 구현
  • 게시글 상세 보기 화면 구현
    등등

모든 화면의 UI가 완성되면, 드디어 Firebase를 연동하여 앱에 실제 데이터를 불어넣는 작업을 시작할 예정입니다. 다음 개발 일지에서 새로운 화면들과 함께 돌아오겠습니다!


#1인개발 #사이드프로젝트 #앱개발 #React_Native #Expo #Expo_Router #UI개발 #개발일지

profile
프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2025년 9월 9일

잘봤습니다 expo go가 복잡한 빌드 과정이 필요 없어서 개발 속도가 많이 빨라진다고 들었어요

1개의 답글