프로필

프로필 사진
Popomon
Frontend Developer
(2020/12 ~)

    카테고리

    포스트

    [React Native/UI Kit 만들기] 그리드 시스템

    2021. 11. 26. 00:24

    꿈가게: To Do List - iOS

    꿈가게: To Do List - Android

    웹페이지나 앱을 만들 때에는 그리드 시스템을 따라서 콘텐츠를 나열하게 됩니다. 웹에서는 12개의 컬럼을 사용하고 앱에서는 4개의 컬럼을 사용합니다.

    그래서 이번 포스팅에서는 React Native 페이지마다 4개의 컬럼을 사용할 수 있도록 그리드 레이아웃을 만들어 보겠습니다.

    그리드 영역의 간격을 나타내는 margin/gutter

    margin 값은 화면 양 끝의 간격을 나타내고, gutter 값은 각 컬럼 사이의 간격을 나타냅니다.

    // Grid System
    export const margin = 20;
    export const gutter = 16;

    그리드 시스템을 적용할 영역을 나타내는 <Container>

    그리드를 적용할 영역을 나타내는 Container 컴포넌트 입니다. backgroundColor 값은 임의로 설정한 것이기 때문에 나중에 지워줍니다.

    import * as React from 'react';
    import { Text, View, StyleSheet, Image } from 'react-native';
    import { margin } from '../constant';
    
    export default function Container({ children }) {
      return (
        <View style={styles.container}>
          {children}
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        flexDirection:"column",
        backgroundColor: '#ecf0f1',
        paddingHorizontal: margin,
      }
    });

    한 줄을 나타내는 <Row>

    한 줄을 나타내는 Row 컴포넌트입니다. 이 한 줄이라는게 정말 애매할 수 있습니다. 기준을 어떻게 잡아야 할까요?

    Figma/Photoshop 과 같이 디자인 협업툴에서 그리드 라인을 확인할 수 있습니다. 그 라인을 보고, 어디서부터 어디까지가 한 줄인지를 알 수 있습니다.

    정말 모르겠다! 싶으시면 그 화면을 디자인 해주신 디자이너님에게 물어보면 바로 알 수 있습니다. 디자이너님들은 한 줄마다 딱딱 그룹화해서 디자인을 해 주시거든요!

    import * as React from 'react';
    import { Text, View, StyleSheet, Image } from 'react-native';
    
    export default function Row({ children }) {
      return (
        <View style={styles.row}>
          {children}
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      row: {
        backgroundColor: '#4052ff',
        flexDirection: "row",
        flex: 1,
      },
    });

    한 열을 나타내는 <Column>

    한 열을 나타내는 Column 컴포넌트입니다. 총 4개의 열로 구성되어 있기 때문에, 웹페이지처럼 배치할 수 있는 종류가 많지 않습니다. 일반적으로는 1단 아니면 2단 레이아웃을 사용하여 배치합니다.

    그렇다면, 왜 겨우 2가지의 레이아웃을 쓰기 위해 이러한 복잡한 시스템을 써야만 하는 걸까요?

    각 화면의 내용이 들어갈 수 있는 경계선을 맞추고, 2단 레이아웃인 경우에는 경계선의 영역의 크기에 맞도록 간격을 띄울 수 있도록 하기 위함입니다.

    import * as React from 'react';
    import { Text, View, StyleSheet, Image, Dimensions } from 'react-native';
    import { margin, gutter } from '../constant';
    
    const fullWidth = Dimensions.get('window').width;
    const columnWidth = (fullWidth - 2 * margin - 3 * gutter) / 4;
    
    export default function Column({ children, colspan = 1, last = false }) {
      return (
        <View 
          style={[
            styles.column, 
            {
              width: columnWidth * colspan + (colspan - 1) * gutter,
              marginRight: last ? 0 : gutter
            }
          ]}
        >
          {children}
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      column: {
        flex: 'none',
        backgroundColor: '#00ff00'
      },
    });

    그리드 시스템을 적용한 샘플 화면