리액트 네이티브(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

_

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