Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

React Native製アプリのフォントサイズをいい感じに設定したい

そとあそび所属の天野(@mutachii) です。

この記事は Akatsuki Advent Calendar 2018 の17日目の記事です。
前回は s-capybaraさんの、Elixir でソースコードジェネレーションする - Qiitaでした。

はじめに

React Nativeでの開発で避けて通れないのは、多種多様なスクリーンで表示崩れを発生させないように実装することです。

幸い、Flexboxのサポートのおかげでレイアウトの実装で困ることは少ないですが、対応が面倒なのが fontSize の指定だと思います。
これらは当然 Flexbox では対応することができないし、widthやheight, paddingなどのようにパーセント指定することもできません。

React Native 開発始めたてのときにあるある(だと思っている)のは、普段は iPhoneX で動作確認している開発者が、
いざリリースするぞとなったタイミングで、iPhone8やiPhoneSEでは文字が大ぎることや、 逆に、iPadで確認すると文字が異様に小さいということに気づき対応に追われるということじゃないでしょうか...

今回は、そのfontSize 問題の解決に有用な

という2つのライブラリを紹介します。

react-native-size-matters

以下のように使うライブラリです。

import { scale, verticalScale, moderateScale } from 'react-native-size-matters';

const Component = props =>
  <View style={{
    width: scale(30), 
    height: verticalScale(50),
    padding: moderateScale(5)
  }}>
    <Text style={{
      fontSize: moderateScale(14)
    }}>すごい</Text>
  </View>

このscaleやverticalScaleがやっていることはすごく単純で、 基準となるスクリーンサイズ(350 x 650)に対する、現在のスクリーンサイズの倍率を算出して、その倍率をかけた数値を返してくれます。 それだけなので、fontSizeはもちろん、widthやheightにも利用できます。

moderateScaleだけはすこし特殊で、

Sometimes you don't want to scale everything in a linear manner, that's where moderate scale comes in.
The cool thing about it is that you can control the resize factor (default is 0.5).
If normal scale will increase your size by +2X, moderateScale will only increase it by +X, for example:
➡️ scale(10) = 20
➡️ moderateScale(10) = 15
➡️ moderateScale(10, 0.1) = 11

というように、増加 / 減少 させるときの係数を指定できます。 スクリーンサイズが2倍になったからといって、すべての要素のサイズを2倍にしたいわけではない...というようなケースで使います。

微妙に問題になるのは、基準となるスクリーンのサイズが 350 x 680 という値なので、例えば デザインデータが iPhoneXで作成されている場合は、デザインどおりに実装できないことです。
とはいえ、上に書いたとおりとてもシンプルな実装なので、自分たちの基準となるスクリーンサイズを使って実装し直すという方法もありそうです。

react-native-responsive-fontsize

名前通りに responsive な fontSize の指定を可能にする RF という関数を提供してくれます。

import RF from "react-native-responsive-fontsize"

const styles = StyleSheet.create({
  welcome: {
    fontSize: RF(3.5),
    textAlign: "center",
    margin: 10
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5,
    fontSize: RF(2.5)
  }
})

こちらの実装もシンプルでデバイスのHeight を基準にフォントサイズを決めます。なので、RFの引数は fontSize ではなくて パーセンテージ であることに注意してください。

さいごに

fontSize問題にすぐ効く2つのライブラリを紹介しました。

基本的には薄い実装のライブラリ達なので、実装の方向性を確認して、自分たちのプロダクトに合わせて改変していくことや、
PRを出してライブラリ自体を改善しやすいのかなと思っています。