Skip to main content

Command Palette

Search for a command to run...

[React Native] 스케일링 함수로 디바이스에 따른 UI 크기 조정

Updated
3 min readView as Markdown
[React Native] 스케일링 함수로 디바이스에 따른 UI 크기 조정

요즘 막 입사해서 온보딩으로 React Native 클론코딩을 하고 있다. React Native를 배운 지 일주일 정도 밖에 되지 않아서 아직 앱 개발에 익숙하지 않지만 온보딩을 통해 조금씩 앱 생태계에 익숙해지고 있다.

🔴 모든 디바이스에서 크기가 고정되어 있는 문제

요즘엔 다양한 디바이스 크기를 고려하여 개발하는 것이 중요하다. 디바이스 크기에 맞지 않는 UI를 그려내면 가독성이 떨어지고 버튼 크기가 작아 클릭이 어려운 문제가 발생할 수 있다. 이런 문제를 해결하기 위해 크기 조정을 잘 해줘야 한다.

하지만 현재 내가 만든 앱은 사이즈에 고정된 숫자를 사용하여 어떤 디바이스에서 앱을 열어도 크기가 고정되어 있다.

아래 이미지는 iPhone SE와 Tablet 디바이스에서 띄웠을 때 차이점을 보여준다.

🔵 화면 크기 기반 스케일링 구현으로 해결

위 문제는 React Native에서 제공하는 Dimensions API를 사용하여 해결할 수 있다. Dimensions API는 디바이스의 화면 크기를 제공한다. 이를 기반으로 스케일링 함수를 구현할 수 있다.

Scaling 함수 구현

import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

const guidelineBaseWidth = 375; // iPhone SE 기준 너비
const guidelineBaseHeight = 667; // iPhone SE 기준 높이

// 가로 스케일 함수
const scale = (size: number) => (width / guidelineBaseWidth) * size;

// 세로 스케일 함수
const verticalScale = (size: number) => (height / guidelineBaseHeight) * size;

// 크기 조정 함수 (가로, 세로 스케일 조합)
const moderateScale = (size: number, factor = 0.5) =>
  size + (scale(size) - size) * factor;

export { scale, verticalScale, moderateScale };

작업 환경인 iPhone SE를 기준삼아 스케일 함수를 구현하였다.

  • scale: 너비를 기준으로 크기를 조정하는 함수

  • verticalScale: 높이를 기준으로 크기 조정하는 함수

  • moderateScale: scale을 기반으로, factor를 통해 더 세밀한 크기 조정 함수, 자연스러운 크기 조정을 위해 사용

Scaling 사용 예시

import React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { scale, verticalScale, moderateScale } from './path-to-your-utils';

const App = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Responsive UI</Text>
      <View style={styles.button}>
        <Text style={styles.buttonText}>Click Me</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  title: {
    fontSize: moderateScale(24),
    marginBottom: verticalScale(20),
  },
  button: {
    width: scale(200),
    height: verticalScale(50),
    borderRadius: moderateScale(10),
  },
  buttonText: {
    fontSize: moderateScale(18),
  },
});

export default App;

사이즈가 적용되는 곳에 함수를 사용할 수 있다.

함수를 적용한 결과, 아래 이미지와 같이 Tablet 디바이스에서도 사이즈가 적절하게 조정되는 것을 알 수 있다.

🟢 moderatorScale은 꼭 있어야 할까?

모든 곳에서 moderatorScale을 사용할 수 있지만, 어떤 상황에 적합한지는 더 고민하고 혼합해서 사용할 수 있다.

moderateScale의 장점

  • 유연성: factor로 조정 강도를 제어할 수 있어서 화면 크기에 따라 UI 크기가 극단적으로 변하지 않도록 한다.

  • 안정성: 크기 변동을 좀 더 완화하기 때문에 모든 디바이스에서 일관된 사용자 경험을 제공할 수 있다.

사용을 고려해야 할 상황

  • 가로/세로 비율에 민감한 요소: 어떤 UI 요소는 화면의 가로나 세로 크기에 비례해 조정되어야 하는 경우가 있다. 예를 들어, 가로 방향에 민감한 버튼이나 텍스트 크기에는 scale을 사용할 수 있다.

  • 특정 레이아웃의 요구사항: 만약 특정 UI 요소가 세로 크기에 따라 강하게 변해야 하는 경우 verticalScale을 사용할 수 있다.

  • 크기 조정이 필요 없는 경우: 어떤 경우에는 화면 크기와 관계없이 고정된 크기가 필요할 수 있다. 이땐 단순한 픽셀 값을 사용하거나 크기 조정을 하지 않는 것이 좋다.

사용 예시

  • 텍스트 크기:moderateScale을 사용하여 화면 크기에 따라 텍스트 크기를 부드럽게 조정할 수 있다. 너무 크거나 너무 작지 않게 조절 가능하여 가독성에 좋다.

  • 버튼: 가로와 세로 비율을 모두 고려해야 한다면 moderateScale을 사용한다. 하지만 가로 너비만 중요하다면 scale을 사용할 수 있다.

  • 이미지: 이미지의 경우 화면 비율을 유지하면서 크기를 조정해야 하므로, scaleverticalScale을 함께 사용할 수 있다.


Reference

Size Matters: How I used React Native to make my App look great on every device

More from this blog

시맨틱하게 다이얼로그 만들기

웹에서 양식을 제출하기 위한 다이얼로그를 작성할 때 시맨틱 태그를 무시하고 div 태그를 활용해 css로 스타일링을 하는 경우가 많다. 이렇게 작성할 경우, 동작에는 전혀 무리가 없지만 하지 않아도 될 스타일링 작업을 하는 데 시간을 쏟을 수 있고 웹접근성 측면에도 좋지 않다. 웹에서 다이얼로그는 모달, 대화상자, 알림창, 검사기와 같은 상호작용 가능한 컴포넌트를 말한다. HTML에서는 dialog 라는 태그를 사용하면 핵심적인 다이얼로그의 기...

Jan 13, 20262 min read

[JavaScript] 이미지 사이즈 압축해서 용량 줄이기

이미지를 받아서 저장하는 기능을 구현하고 며칠이 지난 후 한 가지 이슈를 발견하였다. 바로 이미지 업로드가 되지 않는 아주 치명적인 문제였다! 분명 테스트도 수 없이 진행하고 배포한 후에도 잘만 동작했는데 갑자기 이런 일이 왜 벌어진걸까? 문제 해결의 원인을 찾기 위해 다양한 방법을 시도하였다: 갤럭시의 갤러리에 있는 이미지 업로드 갤럭시의 카메라로 직접 찍어서 업로드 아이폰의 갤러리에 있는 이미지 업로드 아이폰의 카메라로 직접 찍어서 ...

Nov 16, 20242 min read
[JavaScript] 이미지 사이즈 압축해서 용량 줄이기

[JavaScript] 이미지 수정 시 브라우저 캐싱 방지하기

웹 개발을 하면서 한 번쯤 겪어볼 수 있는 이슈가 있다. A 사용자가 이미지를 업로드하면 B 사용자가 그 이미지를 확인하고, 재업로드를 요청하는 플로우다. A 사용자가 새로운 이미지를 업로드 했는데도 B 사용자는 여전히 처음 이미지를 볼 수 있다. 이 문제는 서버 측에서 "이미지 경로는 그대로 유지하고 이미지를 덮어씌운다"는 구조와 관련이 있다. 브라우저는 URL이 동일하면 캐싱된 이미지를 가져와 네트워크 요청을 줄인다. 따라서 새로운 이미지가...

Oct 3, 20242 min read
[JavaScript] 이미지 수정 시 브라우저 캐싱 방지하기

[React] 렌더링 관점에서 보는 react-hook-form (feat. useRef)

평소 한땀한땀 기능을 만들어나가는 걸 좋아해서 유명한 라이브러리들을 사용해보지 않았는데, 회사에서 프로젝트를 진행하며 다양한 라이브러리를 사용해보았다. 그 중 React-Hook-Form을 사용하며 평소에 리액트로 폼을 작성하며 겪은 불편한 점을 많이 해소했다. 코드 길이, 예외 처리, 렌더링 등 다양한 관점에서 개선할 수 있게 되었다. 오늘은 다양한 폼 상태 관리 방법을 비교하여 React-Hook-Form의 장점을 알아보자. useState...

Sep 5, 20243 min read
[React] 렌더링 관점에서 보는 react-hook-form (feat. useRef)

Untitled Publication

53 posts