[React Native] 인스타그램 UI 만들기 #1

안피곤·2019년 1월 22일
53
post-thumbnail

리액트 네이티브(React Native)로 인스타그램 UI을 구현하는 포스팅입니다. 인기있는 앱을 따라 만들어 보는 것은 굉장히 재미있습니다.

구글에서 인스타그램 클론 코딩 강의를 찾아보니, 다른 개발자들이 올린 동영상 강의를 몇 개 찾을 수 있었습니다.

사실 위의 강의 2개는 유료입니다. 저처럼 가난한 개발자는 유료 강의도 가끔 듣지만, 무료 강의를 더 많이 이용합니다. 아래는 유튜브에 공개되어 있는 무료 강의입니다. 이 포스팅은 아래 강의를 듣고 정리한 내용입니다.

_

프로젝트 생성하기

동영상 강의에서는 라이브러리를 먼저 설치하고 프로젝트를 생성하지만, 저는 제 스타일로 프로젝트를 먼저 생성하고 시작합니다.

expo-cli를 이용하여 프로젝트를 생성합니다.

$ expo-cli init instagram-clone
$ cd instagram-clone

expo-cli가 없는 분들은 여기를 참고하세요.

그다음, UI 라이브러리를 설치합니다.

$ yarn add native-base @expo/vector-icons 

yarn이 없으신 분들은 여기를 참고하세요.

그 다음은 네비게이션을 위한 라이브러리를 설치합니다.

$ yarn add react-navigation

_

첫 화면 MainScreen 만들기

Components 폴더를 생성합니다. 그리고 Components 폴더 아래에 MainScreen.js를 생성하고 아래와 같이 입력합니다.

import React, { Component } from 'react';
import { StyleSheet, Platform } from 'react-native';

export default class MainScreen extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>MainScreen</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

_

createStackNavigator 생성하기

App.js 파일을 열어서 수정합니다. App.js 파일 상단에 react-navigation와 방금 만든 ./Components/MainScreenimport 합니다. createStackNavigator() 함수를 사용하여 AppStackNavigator를 생성합니다. 그리고 첫 번째 Navigator에 MainScreen 컴포넌트를 등록합니다.

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import MainScreen from './Components/MainScreen';

const AppStackNavigator = createStackNavigator({
  Main:{
    screen: MainScreen // MainScreen 컴포넌트를 네비게이터에 등록
  }
});

export default createAppContainer(AppStackNavigator);

_

상단 네비게이션 구현하기

native-base에서 Iconimport하고, navigationOptions을 생성합니다. navigationOptions에는 왼쪽에 보여질 ios-camera 아이콘과 오른쪽에 보여질 ios-send 아이콘을 설정합니다.

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Icon } from 'native-base'; // 추가된 코드

export default class MainScreen extends Component {

  // navigationOptions 코드 추가
  static navigationOptions = {
    headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
    title: 'Instagram',
    headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>MainScreen</Text>
      </View>
    );
  }
}

// 이하 코드 생략

_

여기까지 작업한 화면입니다. 상단에 카메라와 비행기 아이콘이 보이나요?

_

탭 네비게이터 구현하기

Components 폴더 아래에 AppTabNavigator 폴더를 생성합니다. 그리고 AppTabNavigator 폴더 아래에 5개의 파일을 생성합니다. HomeTab.js, SearchTab.js, AddMediaTab.js, LikesTab.js, ProfileTab.js 파일을 각각 생성합니다. 생성되는 파일의 내용은 아래와 비슷하게 입력합니다.

import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
 
export default class HomeTab extends Component {
    render() {
        return (
            <View style={style.container}>
                <Text>HomeTab</Text>
            </View>
        );
    }
}
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
});

_

우리가 생성한 파일 구조는 아래와 같습니다.

그 다음은 MainScreen.js 파일을 수정합니다. react-navigationAppTabNavigator 컴포넌트들을 import 합니다. 그리고 하단에 보여줄 탭네비게이터 AppTabNavigator를 생성합니다.

// ... 일부 import 코드 생략 ...

import { createBottomTabNavigator, createAppContainer } from 'react-navigation'; 

// 하단 탭에 들어갈 컴포넌트들
import HomeTab from './AppTabNavigator/HomeTab'
import SearchTab from './AppTabNavigator/SearchTab'
import AddMediaTab from './AppTabNavigator/AddMediaTab'
import LikesTab from './AppTabNavigator/LikesTab'
import ProfileTab from './AppTabNavigator/ProfileTab'

// 하단 탭 네비게이터 생성
const AppTabNavigator = createBottomTabNavigator({
  HomeTab: { screen: HomeTab },
  SearchTab: { screen: SearchTab },
  AddMediaTab: { screen: AddMediaTab },
  LikesTab: { screen: LikesTab },
  ProfileTab: { screen: ProfileTab }
});

const AppTabContainet = createAppContainer(AppTabNavigator);

export default class MainScreen extends Component {
  
 // navigationOptions 코드 생략

  render() {
    return <AppTabContainet/>; // AppTabContainet 컴포넌트를 리턴한다.
  }
}

// ... 이하 코드 생략 ...

동영상 강좌에서는 createTabNavigator를 사용하여 하단 탭 네비게이터를 구현했습니다. 하지만 현재는 createTabNavigatordeprecated 되었습니다. 그래서createBottomTabNavigator 또는 createMaterialTopTabNavigator를 사용해야합니다.

_

여기까지 작업한 화면입니다.

탭 네비게이터에 아이콘 넣기

HomeTab.js 파일을 수정합니다. navigationOptions를 생성하고, Icon을 입력합니다.

// ... 일부 import 코드 생략 ...

import { Icon } from 'native-base';
 
export default class HomeTab extends Component {

    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            <Icon name='ios-home' style={{ color: tintColor }} />
        )
    }

// ... 이하 코드 생략 ...

이어서 SearchTab.js, AddMediaTab.js, LikesTab.js, ProfileTab.js 파일도 수정합니다. 파일에 아이콘을 각각 'ios-search', 'ios-add-circle', 'ios-heart', 'person'로 입력합니다. 각 파일 내용은 깃허브에 업로드된 파일을 참고하세요.

_

여기까지 작업한 화면입니다.

_

탭 네비게이터에 스와이프와 애니매이션 넣기

스와이프와 애니매이션을 넣기 위해서는 createMaterialTopTabNavigator를 사용해야 합니다. 앞에서 createBottomTabNavigator로 구현했던 네비게이터를 createMaterialTopTabNavigator로 수정합니다. 그리고 네비게이터에 옵션을 설정합니다. createMaterialTopTabNavigator 옵션에 대한 자세한 설명은 TabNavigatorConfig 문서를 참고하세요.

// ... 일부 import 코드 생략 ...

// createBottomTabNavigator를 createMaterialTopTabNavigator로 수정
import { createMaterialTopTabNavigator, createAppContainer } from 'react-navigation'; 

const AppTabNavigator = createMaterialTopTabNavigator({
  HomeTab:{ screen: HomeTab },
  Search:{ screen: SearchTab },
  AddMedia:{ screen: AddMediaTab },
  Likes:{ screen: LikesTab },
  Profile:{ screen: ProfileTab }
}, {
  animationEnabled: true,
  swipeEnabled: true,
  tabBarPosition: "bottom",
  tabBarOptions: {
    style: {
      ...Platform.select({
        ios:{
          backgroundColor:'white',
        }
      })
    },
    iconStyle: { height: 100 },
    activeTintColor: '#000',
    inactiveTintColor: '#d1cece',
    upperCaseLabel: false,
    showLabel: false,
    showIcon: true,
  }
});

// ... 이하 코드 생략 ...

_

여기까지 작업한 화면입니다.

이제 하단 탭 아이콘을 클릭하면 페이지 슬라이드 애니메이션이 발생합니다.

_

작업한 코드는 모두 깃허브에 업로드되어 있습니다.

https://github.com/anpigon/rn_instagram_clone

_

여기까지 읽어주셔서 감사합니다.

profile
꿈꾸는 개발자. 저는 스팀잇에서 활동하고 있습니다. @anpigon

26개의 댓글

comment-user-thumbnail
2019년 1월 22일

👍👍

1개의 답글
comment-user-thumbnail
2019년 1월 22일

매우 흥미로운 포스트입니다! 감사합니다

1개의 답글
comment-user-thumbnail
2019년 1월 23일

잘 봤어요. 어떻게 만드나 싶었는데 갈증이 해소되는 느낌입니다.

1개의 답글
comment-user-thumbnail
2019년 1월 23일

헬로월드만 한번 띄워봤는데 빌드했더니 QR코드를 통해 앱으로 전송하더군요 신기해요

1개의 답글
comment-user-thumbnail
2019년 1월 25일

그런데 유료강의에서 강의내용을 가져와도 괜찮은 거죠?

1개의 답글
comment-user-thumbnail
2019년 2월 18일

아니~ 책을 출간하고 방대한 지식을 가지신 분이~ "저처럼 가난한 개발자는 유료 강의도 가끔 듣지만, 무료 강의를 더 많이 이용합니다." 다른 사람의 강의도 보시나요? ㅎㅎ. "리액트를 다루는 기술" 잘 보고 있습니다. 감사합니다. 다음에는 네이티브 실전앱 제작하는 책이 하나 발간되었으면 좋겠습니다. 실제 리액트가 네이티브를 지향하는데 시중에는 실전 ios, 안드로이드 배포까지 만드는 과정이 없더군요. ㅠㅜ.

1개의 답글
comment-user-thumbnail
2019년 4월 25일

잘보았습니다~제 블로그에 참조 링크걸고 포스팅해도 될까요??

1개의 답글
comment-user-thumbnail
2019년 5월 13일

좋은 글 감사합니다.
아이폰을 기준으로는 버그가 없을 것 같은데 안드로이드에서 버그가 조금 있습니다.
먼저 탭 네비게이터를 생성할 때 bounces 옵션을 안드로이드에서는 넣어줘야 합니다.
옵션에 bounces: true라고 부여하면 됩니다. 또한 위의 코드대로 실행하면 iOS에 대해서만 탭 네비게이터의 색상이 정해진 상태라 파란색 배경으로 나타나는데 ios:{ background: white } 아래에 android: { background: white }라고 해주면 이 부분도 해결됩니다. 또한 글의 첫번째 코드의 클래스명을 App이 아닌 MainScreen입니다. 따라하시는 분들이 헷갈리실거 같아 몇글자 적어봅니다.

1개의 답글
comment-user-thumbnail
2019년 10월 21일

포스트 잘 봤습니다.
혹시 createMaterialTopTabNavigator 에서 좌우 스와이프를 커텐츠 화면에서 손으로 좌우 제스처로 가능하게할수 있을까요?

1개의 답글
comment-user-thumbnail
2020년 1월 8일

ㅎㅎㅎ 가끔 와서 구경 하겠습니다.

답글 달기