[React Native] 시스템 폰트 크기 설정 막기

호이·2025년 1월 20일
0

React Native

목록 보기
10/10

1. 왜 필요한가?

React Native 프로젝트를 진행하면서 모바일 디바이스의 폰트 크기 설정으로 인해 앱 디자인이 이상해지는 문제가 발생했다. 모바일 앱 특성상 사용자의 폰트 크기 설정에 영향을 받을 수 밖에 없는데, 이를 막는 것은 매우 좋지 않은 해결방법이다. 하지만 프로젝트 기간 안에 앱의 디자인이 깨져버리는 것을 수정해야 했고, 이 원인의 해결방안으로 우선 모바일의 시스템 폰트 크기 설정에 대해 영향을 안 받도록 수정하는 것이였다.

2 과정

여러 라이브러리를 적용하면 반응형으로 폰트 크기를 설정할 수 있지만, 단순히 앱에서 적용된 폰트 크기대로 설정해주면 되는 문제라 우선 시스템 폰트 크기 설정만 영향을 받지 않도록 수정하는 방향대로 가기로 하였다.

3. 결과

여러 구글링을 거쳐 온 결과 아래의 방법대로 코드를 적용하면 안드로이드와 아이폰에서 시스템 폰트 크기를 설정에 대한 영향을 막을 수 있다.

1. 안드로이드

  • android/app/src/main/java/[패키지경로]MainApplication.java에서 다음과 같이 추가한다.
// 패키지 임포트
import android.view.WindowManager;
import android.content.res.Configuration;
import android.content.Context;
import android.util.DisplayMetrics;

// onCreate메서드에서 super.onCreate()구문 밑에 추가
adjustFontScale(getApplicationContext(),getResources().getConfiguration());

// onCreate메서드 밑에 추가
public void adjustFontScale(Context context, Configuration configuration) {
  if (configuration.fontScale != 1) {
    configuration.fontScale = 1;
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
    metrics.scaledDensity = configuration.fontScale * metrics.density;
    context.getResources().updateConfiguration(configuration, metrics);
  }
}
  • 코드를 적용하면 이러한 모습이 된다
package com.reactnativetest;

import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;

// 패키지 임포트
import android.view.WindowManager;
import android.content.res.Configuration;
import android.content.Context;
import android.util.DisplayMetrics;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new DefaultReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }

        @Override
        protected boolean isNewArchEnabled() {
          return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
        }

        @Override
        protected Boolean isHermesEnabled() {
          return BuildConfig.IS_HERMES_ENABLED;
        }
      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    adjustFontScale(getApplicationContext(),getResources().getConfiguration()); // 추가
    SoLoader.init(this, /* native exopackage */ false);
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      DefaultNewArchitectureEntryPoint.load();
    }
    ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

  // 추가
  public void adjustFontScale(Context context, Configuration configuration) {
    if (configuration.fontScale != 1) {
      configuration.fontScale = 1;
      DisplayMetrics metrics = context.getResources().getDisplayMetrics();
      WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      wm.getDefaultDisplay().getMetrics(metrics);
      metrics.scaledDensity = configuration.fontScale * metrics.density;
      context.getResources().updateConfiguration(configuration, metrics);
    }
  }
}
  • 코드를 적용하면 안드로이드를 재빌드한다.

2. ios

  • index.js에서 다음과 같이 코드를 추가한다.
import { Text, TextInput } from "react-native";

if (Text.defaultProps == null) {
  Text.defaultProps = {};
  Text.defaultProps.allowFontScaling = false;
  TextInput.defaultProps = TextInput.defaultProps || {};
  TextInput.defaultProps.allowFontScaling = false;
}
  • 코드가 적용되면 이러한 모습이다.
import {AppRegistry, Text, TextInput} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

if (Text.defaultProps == null) {
  Text.defaultProps = {};
  Text.defaultProps.allowFontScaling = false;
  TextInput.defaultProps = TextInput.defaultProps || {};
  TextInput.defaultProps.allowFontScaling = false;
}
  • 코드를 적용한 후 재빌드를 한다.
profile
기억하기 싫어서 기록하는 작은 공간

0개의 댓글