안녕하세요. 김용성입니다.
이전 포스팅에서는 제가 웹에서의 responsive units을 설명드렸는데요.
혹시 앱에서는 이러한 것들을 어떻게 처리해야할지 알고계시나요?
예를들어 작년에 아이폰 12가 나왔죠? 그 중에서 아이폰 12미니와 아이폰 12 max의 크기차이는 상당히 큽니다. 우리가 이러한 부분들에 대해 고려하지 않고, 고정된 값을 사용하여 보여지는 simulator에서만 그럭저럭 괜찮게 UI를 만들어놓는다면? 나중에 큰 문제가 생길 수도 있겠죠?
그래서 오늘은 react-native로 앱을 만들 때 이러한 부분에 대해 미연에 방지하고, 디바이스 별 크기에 따라 폰트 크기나, container크기가 잘 적용될 수 있게 하는 방법을 간단하게 포스팅하고자 합니다.
최근에 진행했던 졸업작품 frontend 디렉토리에서 가져왔는데요. 저는 react-native 프로젝트를 진행할 때 주로 위와 같은 디렉토리 구조를 선호합니다.
오늘의 중요한 것은 디렉토리 구조가 아니니 이에 대한 설명은 생략하고 쭉쭉 내려가다보면 config라는 디렉토리가 보일텐데요. 주로 저는 이 config 디렉토리 내에서 globalStyles라고 앱 전역적으로 사용될만한 스타일 변수들을 모아놓고 export/import 해서 사용합니다. 이러한 것에 대해 설명드리는 이유는, 오늘 제가 알려드린 부분을 일일이 컴포넌트 내에서 styling하지 마시고, 이렇게 전역적인 스타일 변수를 사용할 경우에 작업이 훨씬 편해진다는 것을 알려드리고 싶어서였습니다. :)
여튼 config 파일 내의 globalStyles라는 파일을 한번 살펴보도록 하겠습니다.
//globalStyles.js
import {Dimensions} from 'react-native';
export const colors = {
primary: '#EC8B57',
black: '#191919',
red: '#FF3636',
lightBlue: '#36D2FF',
green: '#8FEF73',
grey: '#767676',
borderGrey: '#C9C9C9',
statusGrey: '#666666',
textGrey: '#A2A2A2',
darkBlue: '#83abeb',
};
export const fonts = {
SpoqaHanSansNeo: 'SpoqaHanSansNeo',
SpoqaHanSansNeo_Thin: 'SpoqaHanSansNeo-Thin',
SpoqaHanSansNeo_Light: 'SpoqaHanSansNeo-Light',
SpoqaHanSansNeo_Medium: 'SpoqaHanSansNeo-Medium',
SpoqaHanSansNeo_Regular: 'SpoqaHanSansNeo-Regular',
SpoqaHanSansNeo_Bold: 'SpoqaHanSansNeo-Bold',
};
export const basicDimensions = { // 디자이너가 작업하고 있는 XD파일 스크린의 세로,가로
height: 740,
width: 360,
};
export const height = ( // 높이 변환 작업
Dimensions.get('screen').height *
(1 / basicDimensions.height)
).toFixed(2);
export const width = ( // 가로 변환 작업
Dimensions.get('screen').width *
(1 / basicDimensions.width)
).toFixed(2);
react-native의 요소 중에는 Dimensions라는 녀석이 있어요.
이 녀석을 통해서 현재 사용하고 있는 screen의 가로, 세로 값을 가져올 수가 있는데요. 이제 이렇게 가져온 녀석을 나누어줍니다.
어떤 값으로 나눌까요?
저 같은 경우, 위 코드를 짤 때에는 제가 직접 XD파일을 만들었었어요. 그때 XD 스크린을 높이 740px, 가로 360px으로 지정해둔 채 만들었기 때문에 저는 해당 값을 BasicDimensions라는 변수를 통해서 정의해주었습니다.
(각자 zeplin이나 XD를 보면서 저 변수는 설정해주면 됩니다!)
저렇게 해서 만들어진 width,height는 우리가 이제 컴포넌트에서 폰트와 컨테이너의 크기작업을 해줄 때 아주아주 용이하답니다. :)
import React from 'react';
import {StyleSheet, View, TouchableOpacity, Text} from 'react-native';
import {colors, width, height} from '../config/globalStyles'; //width,height 받아오기
import MyIcon from '../config/Icon-font.js';
return (
<View style={styles.notification}>
<TouchableOpacity activeOpacity={0.8} style={styles.notification}>
<View style={styles.notificationBody}>
<MyIcon
name={'alarm-3'}
size={width * 25} <!--아이콘에서도-->
color={colors.borderGrey}
/>
<Text style={styles.notificationContent}>{content}</Text>
</View>
<Text style={styles.notificationTime}>방금 전</Text>
</TouchableOpacity>
</View>
);
};
export default Notification;
const styles = StyleSheet.create({
notification: {
width: '100%',
height: height * 70, //높이를 지정해줄 때도
backgroundColor: colors.bottomTabBarBackgroundColor,
padding: width * 10, // padding 값을 줄 때도
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
notificationBody: {
flexDirection: 'row',
alignItems: 'center',
},
notificationContent: {
marginLeft: width * 10, // margin 값을 줄 때도
fontSize: width * 13, // 폰트 사이즈를 지정해줄 때도!
},
notificationTime: {
fontSize: width * 11,
color: colors.grey,
},
});
위 코드를 보시면 우리가 globalStyles에서 한번 정의한 width,height를 가지고 컨테이너의 width/height 그리고 padding/margin, 게다가 폰트 사이즈까지 선언할 수가 있다는 것을 확인할 수 있습니다.
(xd파일의 width/height 표시창)
XD에서 보여지는 width/height 비율과 같기 때문에 초기 디자인에서 원하던 모습을 여러 디바이스에서 충족시킬 수가 있죠.
늘 사용하던 맥북이 지금 잠시 고장이 난 것 같아, 여러가지 스크린샷과 함께 설명드리고 싶었는데 그러지 못해 아쉽네요. ㅜㅜㅜㅜㅜ
종강 후에 맥북을 고치면 설명한 내용을 보다 더 직관적으로 보실 수 있도록 몇가지 스크린샷을 추가하도록 하겠습니다.
읽어주셔서 감사합니다:)
안녕하세요 글 잘 읽고있습니다. 궁금한게 하나 있습니다
notification style의 height: height 70가 의미하는게 무엇인가요??
basicDimensions이 360x740이고, 실 기기의 사이즈가 390x844 일때
height는 1.14가 나오고 width는 1.08가 나오는데요
1.14에서 70을 곱하면 79.8이 나옵니다.
70을 지정하신건 basicDimensions(360x740)을 기준으로 height가 70인 크기를 실 기기(390 x 844)에서도 70의 크기를 갖게 한다는 의미인가요?
예를들어 시뮬레이터에서 아이폰12(390x844)으로 버튼을 만드는데, 높이를 height:30로 지정하지 않고 글 내용을 적용한대로 height: height 30 을 한다면 아이폰6s같은 작은 기기에서도 동일한 비율로 나오는건가요?
글을 장황하게 두서없이 썼는데,, 제가 궁금한건 height: height * 70이 어떤 효과를 가져오는지..에 대한 질문이었습니다.