如何在React Native中设置默认字体系列?


98

React Native中是否有与此CSS等效的字体,以便该应用程序各处都使用相同的字体?

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

在每个“文本”节点上手动应用它似乎过于复杂。


1
对这个问题有任何完美的答案吗?我不想调用任何styles.text或类似的名称。
MD Ashik '17

Answers:


70

推荐的方法是创建自己的组件,例如MyAppText。MyAppText是一个简单的组件,可以使用通用样式来呈现Text组件,并且可以通过其他道具等。

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


2
谢谢,这正是我所需要的。似乎我还没有足够深入地了解组件方法:)
Dagobert Renouf

2
在文档中还不清楚的一件事是如何通过组件中的属性以及如何尊重组件上的样式。您可以这样做:gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar

1
@NeilSarkar该要点示例的一个问题是样式是在构造函数中生成的。结果,如果样式道具更改,则希望它重新渲染,但在这种情况下不会。应该在render()而不是构造函数中进行处理。useMemo如果效率很重要,则将钩子与配合使用也可能会有所帮助。另外,如果要将其保留在构造函数中,则重要的是添加一个componentDidUpdate逻辑,该逻辑this.style在组件由于样式属性更改而更新时进行更新。
Fernando Rojo

好点,谢谢!好像有人也将重构版本添加到要点中,该版本在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以及您提供的任何其他prop /样式。


尽管这是一个很酷的技巧,但使用惯用的成分组合方法似乎是一个更好的选择。
丹尼尔·利特尔

当Text组件不支持开箱即用更改默认字体时,此解决方案会变得更好。我宁愿在一处添加一个全局控件并使用本机组件,而不是为真正的本机应用程序提供的每个细节都创建一个包装器组件。
mienaikoe '17

我在上述2个解决方案之间犹豫了一下,实际上我讨厌安装非官方的插件,导致react-native本身继续发生变化,但是最后我选择了这个插件,因为它确实可以节省大量时间。谢谢!
张巴兹

所以我需要打电话<Text style={styles.text}>?这不是一个完美的解决方案,就像body {font-family: 'Open Sans';} 有任何更新解决方案一样?
MD Ashik '17

1
不,你不需要做Text style={styles.text}>。您只需要在应用程序中的某个位置声明自定义道具,它将被应用到所有Text组件。这非常类似于body {font-family: ....}
Ajackster,

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
不幸的是,如果我们重写styleprop来调整特定Text组件的样式,它将无法正常工作
Amerzilla '18

没错,但是您可以解决此问题,创建一个通用样式作为对象,并且每当您想要一些自定义字体时,只需将包含该对象+ yourNewStyleObject @Amerzilla的数组传递给该组件
AJA

1
那里有问题。如果有人随后style在Text组件中定义了prop,则将替换默认字体。
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'}},原点。 [props.style]。否则,您将覆盖组件中设置的自定义样式
Iaconis Simone,

1
表现最好。Text.prototype.render不再起作用,Text.render起作用!
基拉

1
如何避免图标继承相同?
暴民

1
我同意@IaconisSimone的最佳方法来设置fontFamily,并确保不要覆盖自定义样式
dczii

1
这就是要走的路
Witalo Benicio

15

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

package.json 然后运行react-native link


14

使用React-Native 0.56,以上更改方法 Text.prototype.render不再起作用,因此您必须使用自己的组件,这可以一行完成!

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

如果我的App.js主要由const App = StackNavigator({...})export default App哪儿我把这个代码,我不认为我可以在这里使用一个构造函数?
kojow7 '18

我在这里加了我自己的问题:stackoverflow.com/questions/50081042/...
kojow7

为什么构造函数要超过componentDidMount?
Dror Bar '18

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链接”将资产添加到我们的本机应用程序中。

验证或手动执行。

这应该将字体名称添加到项目中.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 native应用程序中使用。

现在-em现在设置默认字体。

然后设置默认字体以在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 '18

2

在package.json中设置

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

和链接反应本机链接


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.