React Nativeでデフォルトのフォントファミリーを設定する方法


98

React NativeにこのCSSに相当するものがあるので、アプリはどこでも同じフォントを使用しますか?

body {
  font-family: 'Open Sans';
}

すべてのTextノードに手動で適用するのは非常に複雑に見えます。


1
この質問に完璧な答えがありますか??? styles.textやそのようなものを呼び出したくありません。
MD Ashik 2017

回答:


70

MyAppTextなどの独自のコンポーネントを作成することをお勧めします。MyAppTextは、ユニバーサルスタイルを使用してテキストコンポーネントをレンダリングし、他の小道具などを通過できる単純なコンポーネントです。

https://facebook.github.io/react-native/docs/text.html#limited-style-inheritance


2
ありがとう、それがまさに私が必要としていたことです。コンポーネントのアプローチをまだ十分に理解していないようです:)
Dagobert Renouf

2
ドキュメントから明確ではないことの1つは、コンポーネントのプロパティをどのようにパススルーし、コンポーネントのスタイルを尊重するかです。これは次のようにして行うことができます:gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar

1
@NeilSarkarその要旨の例の1つの問題は、スタイルがコンストラクターで生成されることです。その結果、スタイルプロップが変更された場合、再レンダリングする必要がありますが、この場合は変更されません。render()コンストラクタの代わりに処理する必要があります。でフックを使用useMemoすると、効率が重要な場合にも役立ちます。または、コンストラクター内に保持したい場合は、スタイルプロップの変更によりコンポーネントが更新されたときにcomponentDidUpdate更新さthis.styleれるロジックを追加することが重要です。
フェルナンドロホ

良い点、ありがとう!(純粋なコンポーネントの)renderメソッドのスタイルを組み合わせるリファクタリングされたバージョンも要点に追加されたようです
Neil Sarkar

58

最近、この問題を解決するために作成されたノードモジュールがあったため、別のコンポーネント作成する必要はありません

https://github.com/Ajackster/react-native-global-props

https://www.npmjs.com/package/react-native-global-props

ドキュメントには、最上位のコンポーネントにそのsetCustomTextような関数をインポートすることが記載されています。

import { setCustomText } from 'react-native-global-props';

次に、react-native Textコンポーネントに必要なカスタムスタイル/プロパティを作成します。あなたの場合、fontFamilyがすべてのTextコンポーネントで機能するようにします。

const customTextProps = { 
  style: { 
    fontFamily: yourFont
  }
}

setCustomText関数を呼び出して、小道具/スタイルを関数に渡します。

setCustomText(customTextProps);

そして、すべてのreact-native Textコンポーネントには、宣言したfontFamilyと、提供する他のすべての小道具/スタイルがあります。


これはクールなハックですが、コンポーネント構成を使用する慣用的な方法はより良い選択のようです。
ダニエルリトル

テキストコンポーネントがデフォルトのフォントの変更をサポートしていない場合、このソリューションはより優れたものになります。真のネイティブアプリが提供するすべての詳細に対してラッパーコンポーネントを作成するのではなく、1か所にグローバルコントロールを追加してネイティブコンポーネントを使用したいのです。
mienaikoe

私は上記の2つのソリューションの間で迷っていましたが、実際には非公式のプラグインをインストールするのが嫌いです。ありがとう!
Zhang Buzz 2017年

だから私は電話する必要があります<Text style={styles.text}>か?それbody {font-family: 'Open Sans';} は更新ソリューションを持っているような完璧なソリューションではありませんか?
MD Ashik 2017

1
いいえ、必要はありませんText style={styles.text}>。アプリケーションのどこかにカスタムプロップを宣言するだけで、すべてのテキストコンポーネントに適用されます。それは非常に似ていますbody {font-family: ....}
アジャックスター2017

31

React Native 0.56.0以降の場合、defaultPropsが最初に定義されているかどうかを確認します。

Text.defaultProps = Text.defaultProps || {}

それから加えて:

Text.defaultProps.style =  { fontFamily: 'some_font' }

上記をApp.jsファイル(または、使用しているルートコンポーネント)のコンストラクターに追加します。

スタイルを上書きするためには、(例えばスタイルオブジェクトを作成し、それは、あなたの追加のスタイルを追加広げることができます{ ...baseStyle, fontSize: 16 }


4
多分defaultProps他のすべての答えが書かれたときに存在しなかったかもしれませんが、これは今それを行う方法のようです。
freeall

4
残念ながら、styleたとえば特定のTextコンポーネントのスタイルを微調整するためにprop をオーバーライドする場合は機能しません
Amerzilla

Trueですが、これを回避し、共通のスタイルをオブジェクトとして作成できます。カスタムフォントが必要な場合は常に、そのオブジェクトを含む配列+ yourNewStyleObject @Amerzilla
AJA

1
そこに問題があります。その後、誰かstyleがTextコンポーネントでプロップを定義すると、デフォルトのフォントが置き換えられます。
Broda Noel

2
それは2019年であり、完全に機能しています。Androidではファイル名に「-」を使用できないことを覚えておいてください。font_name.ttfのようなフォントファイル名を定義します。
MRSafari

23

Textを使用してコンポーネントのいずれかにこれを追加することにより、Textの動作をオーバーライドできます。

let oldRender = Text.prototype.render;
Text.prototype.render = function (...args) {
    let origin = oldRender.call(this, ...args);
    return React.cloneElement(origin, {
        style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
    });
};

編集:React Native 0.56以降、Text.prototype動作しなくなりました。を削除する必要があります.prototype

let oldRender = Text.render;
Text.render = function (...args) {
    let origin = oldRender.call(this, ...args);
    return React.cloneElement(origin, {
        style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
    });
};

4
これは素晴らしい解決策ですが、[origin.props.style、{color: 'red'、fontFamily: 'Arial'}]-> [{color: 'red'、fontFamily: 'Arial'}、originを変更する必要があります。 props.style]そうでない場合は、コンポーネントに設定されたカスタムスタイルをオーバーライドします
Iaconis Simone

1
うまくいきました。Text.prototype.renderは機能しなくなり、Text.renderは機能します。
吉良

1
アイコンが同じものを継承しないようにするにはどうすればよいですか?
mob

1
fontFamilyを設定し、カスタムスタイルを上書きしないようにする@IaconisSimoneの最善の方法に同意します
dczii

1
これが先の方法です
Witalo Benicio

15

追加

"rnpm": {
  "assets": [
 "./assets/fonts/"
  ]
}

package.json 、次に実行しますreact-native link


14

React-Native 0.56では、上記の変更方法はText.prototype.render機能しなくなったため、独自のコンポーネントを使用する必要があります。これは1行で実行できます。

MyText.js

export default props => <Text {...props} style={[{fontFamily: 'Helvetica'}, props.style]}>{props.children}</Text>

AnotherComponent.js

import Text from './MyText';

...
<Text>This will show in default font.</Text>
...

@FancyJohnフックとになりましたuseRefreactjs.org/docs/hooks-reference.html#useref
Christopher Reid

11

この関数をルートAppコンポーネントに追加し、これらの手順を使用してフォントを追加した後、コンストラクタから実行します。https://medium.com/react-native-training/react-native-custom-fonts-ccc9aacf9e5e

import {Text, TextInput} from 'react-native'

SetDefaultFontFamily = () => {
    let components = [Text, TextInput]

    const customProps = {
        style: {
            fontFamily: "Rubik"
        }
    }

    for(let i = 0; i < components.length; i++) {
        const TextRender = components[i].prototype.render;
        const initialDefaultProps = components[i].prototype.constructor.defaultProps;
        components[i].prototype.constructor.defaultProps = {
            ...initialDefaultProps,
            ...customProps,
        }
        components[i].prototype.render = function render() {
            let oldProps = this.props;
            this.props = { ...this.props, style: [customProps.style, this.props.style] };
            try {
                return TextRender.apply(this, arguments);
            } finally {
                this.props = oldProps;
            }
        };
    }
}

これはまさに私が探していたもので、これ以上インストールしたくありませんでした。
zevy_boy 2018年

私のApp.jsが主に構成されてconst App = StackNavigator({...})おりexport default App、ここでコンストラクタを使用できないと思うので、このコードを正確にどこに配置すればよいですか?
kojow7

私はここで自分の質問を追加しました:stackoverflow.com/questions/50081042/...
kojow7

なぜcomponentDidMountのコンストラクタですか?
Dror Bar

2

このスレッドに遅れるが、ここに行く。

TLDR; 次のブロックをAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 ....
    // HERE: replace "Verlag" with your font
  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

全体の流れのウォークスルー。

次のようなプラグインを使用する以外にこれを行うことができるいくつかの方法 react-native-global-propsので、順を追って説明します。

プラットフォームにフォントを追加する。

フォントをIOSプロジェクトに追加する方法

まず、アセットの場所を作成しましょう。ルートに次のディレクトリを作成してみましょう。

「」

ios/
static/
       fonts/

「」

次に、package.jsonに「React Native」NPMを追加します。

  "rnpm": {
    "static": [
   "./static/fonts/"
    ]
  }

これで「react-native link」を実行して、アセットをネイティブアプリに追加できます。

手動で確認または実行する。

フォント名がプロジェクトに追加されます.plist (VSコードの場合、ユーザーはcode ios/*/Info.plist確認のためにするため)

ここで、Verlag追加したフォントを想定します。次のようになります。

     <dict>
   <plist>
      .....
      <key>UIAppFonts</key>
      <array>
         <string>Verlag Bold Italic.otf</string>
         <string>Verlag Book Italic.otf</string>
         <string>Verlag Light.otf</string>
         <string>Verlag XLight Italic.otf</string>
         <string>Verlag XLight.otf</string>
         <string>Verlag-Black.otf</string>
         <string>Verlag-BlackItalic.otf</string>
         <string>Verlag-Bold.otf</string>
         <string>Verlag-Book.otf</string>
         <string>Verlag-LightItalic.otf</string>
      </array>
      ....    
</dict>
</plist>

それらをマッピングしたので、実際にそこにあり、ロードされていることを確認しましょう(これは手動で行う方法でもあります)。

に移動し"Build Phase" > "Copy Bundler Resource"ます。うまくいかなかった場合は、ここに手動で追加します。

1_uuz0__3kx2vvguz37bhvya

フォント名を取得(XCodeで認識)

まず、次のようなXCodeログを開きます。

XXXX

次に、次のブロックをに追加してAppDelegate.m、フォントとフォントファミリの名前をログに記録できます。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    .....


  for (NSString* family in [UIFont familyNames])
  {
    NSLog(@"%@", family);
    for (NSString* name in [UIFont fontNamesForFamilyName: family])
    {
      NSLog(@" %@", name);
    }
  }

  ...
}

実行すると、正しくロードされていればフォントが見つかるはずです。ここでは、次のようなログでフォントを見つけました。

2018-05-07 10:57:04.194127-0700 MyApp[84024:1486266] Verlag
2018-05-07 10:57:04.194266-0700 MyApp[84024:1486266]  Verlag-Book
2018-05-07 10:57:04.194401-0700 MyApp[84024:1486266]  Verlag-BlackItalic
2018-05-07 10:57:04.194516-0700 MyApp[84024:1486266]  Verlag-BoldItalic
2018-05-07 10:57:04.194616-0700 MyApp[84024:1486266]  Verlag-XLight
2018-05-07 10:57:04.194737-0700 MyApp[84024:1486266]  Verlag-Bold
2018-05-07 10:57:04.194833-0700 MyApp[84024:1486266]  Verlag-Black
2018-05-07 10:57:04.194942-0700 MyApp[84024:1486266]  Verlag-XLightItalic
2018-05-07 10:57:04.195170-0700 MyApp[84024:1486266]  Verlag-LightItalic
2018-05-07 10:57:04.195327-0700 MyApp[84024:1486266]  Verlag-BookItalic
2018-05-07 10:57:04.195510-0700 MyApp[84024:1486266]  Verlag-Light

これで、Verlagファミリが読み込まれ、そのファミリ内のフォントであることがわかりました

  • Verlag-Book
  • Verlag-BlackItalic
  • Verlag-BoldItalic
  • Verlag-XLight
  • Verlag-Bold
  • Verlag-Black
  • Verlag-XLightItalic
  • Verlag-LightItalic
  • Verlag-BookItalic
  • Verlag-Light

これらは、reactネイティブアプリで使用できるフォントファミリで使用できる大文字と小文字が区別される名前になりました。

わかった-デフォルトのフォントを設定した。

次に、デフォルトのフォントを設定してAppDelegate.m、この行でフォントファミリー名を追加します

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 ....
    // ADD THIS LINE (replace "Verlag" with your font)

  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

できました。


RN 0.57の最新の更新に関連する何か、最善のアプローチは機能していませんか?
user2976753 2018年

2

package.jsonで設定

"rnpm": {
  "assets": [
     "./assets/fonts/"
  ]
}

そして、リンクネイティブリンク


1

私にとってはうまくいきます:React Nativeでカスタムフォントを追加します

フォントをダウンロードして、assets / fontsフォルダーに配置し、この行をpackage.jsonに追加します

 "rnpm": {
"assets": ["assets/fonts/Sarpanch"]}

次にターミナルを開いて次のコマンドを実行します:react-native link

これで準備は完了です。詳細な手順については、上記のリンクにアクセスしてください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.