如何设置默认字体家族在反应本机?

是否有一个等效的 CSS 在反应本机,使应用程序使用相同的字体无处不在?

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

在每个 Text 节点上手动应用它似乎过于复杂。

206636 次浏览

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

Https://reactnative.dev/docs/text#limited-style-inheritance

最近制作了一个节点模块来解决这个问题,所以 不要必须使用 创建另一个组件

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';

然后,为反应本机 Text组件创建所需的自定义样式/道具。在您的例子中,您希望 FontFamily处理每个 Text组件。

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

调用 setCustomText函数并将道具/样式传递给函数。

setCustomText(customTextProps);

然后,所有反应原生 Text组件将有您声明的 FontFamily以及您提供的任何其他道具/样式。

您可以通过使用 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]
});
};

编辑: 自从反应原生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]
});
};

对于 React Native0.56.0 + ,检查是否首先定义了 defaultProps:

Text.defaultProps = Text.defaultProps || {}

然后加上:

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

在 App.js 文件的构造函数(或者您拥有的任何根组件)中添加上述内容。

为了重写样式,您可以创建一个样式对象并将其展开,然后添加其他样式 (例如 { ...baseStyle, fontSize: 16 })

将此函数添加到您的根 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;
}
};
}
}

这个话题已经很晚了,不过我要说了。

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 Natural”NPM

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

现在我们可以运行“反应-本地链接”将我们的资产添加到我们的本地应用程序。

手动验证或执行。

这应该将您的字体名称添加到项目 .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

现在,我们可以在我们的字体家族中使用这些区分大小写的名称,我们可以在我们的本地应用程序中使用这些名称。

现在设置默认字体。

然后设置一个默认字体,用这一行在 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]];
....
}

成交。

对于 React-Native0.56,上述更改 Text.prototype.render的方法不再有效,因此您必须使用您自己的组件,这可以在一行中完成!

MyText.js

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

另一个组件

import Text from './MyText';


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

这对我很有用: 在“反应本机”中添加自定义字体

下载您的字体并将它们放在 asset/fonts 文件夹中,然后将这一行添加到 package.json 中

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

然后打开终端并运行以下命令: 反应-本机链接

现在你可以去。更详细的步骤。访问上面提到的链接

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

package.json 然后运行 react-native link

设置在包中。 json

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

和链接反应-本地链接

对于 React Nativeversion ≥0.60,在根文件中创建一个名为 react-native.config.js的文件并放入以下内容,然后只运行 react-native link

module.exports = {
assets: ["./assets/fonts"]
}

对于机器人来说,这对我很有用。

创建一个名为 font 的文件夹

机器人应用程序

在字体文件夹中插入你的 font.ttf/. otf,确保字体名称是小写字母并且只有下划线。

例句:-rubik _ rules. ttf

添加下面一行

Android 应用程序 src main res value styles.xml

<item name="android:fontFamily">@font/font_name</item>

比如说,

<resources>
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:fontFamily">@font/rubik_regular</item>
</style>


...


</resources>

确保重新运行你的应用程序。

另外,我们可以像这样添加字体大小和字体颜色

<resources>
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#008</item>
<item name="android:fontFamily">@font/rubik_regular</item>
</style>


...


</resources>

当我使用 v0.63的时候,这个回答 曾经对我有用,但是当我把 react-native升级到 v0.66.4的时候,它就坏了。

我认为 Text组件的实现已经发生了变化。

我想到了这个办法:

    const oldTextRender = Text.render;


Text.render = function(...args) {
const origin = oldTextRender.call(this, ...args);
const children = origin.props.children;


if (typeof children === 'object') {
return React.cloneElement(origin, {
children: React.cloneElement(children, {
style: [ { fontFamily: 'CustomFontFamily' }, children.props.style ]
})
});
}


return React.cloneElement(origin, {
style: [ { fontFamily: 'CustomFontFamily' }, origin.props.style ]
});
};


请注意,children道具可能是一个 object,例如,它可能是一个 LogBoxMessage组件。但是在屏幕上呈现的正常文本的 children道具类型是 string的类型。

您可能希望使用递归函数将 fontFamily应用于 children

若要具有不带样式 LogBox的默认字体样式,请参见:

import React from 'react'
import { Text } from 'react-native'


import yourStyle from './yourStyle'


export default function setGlobalFontFamily() {
const oldTextRender = Text.render


Text.render = function (...args) {
const origin = oldTextRender.call(this, ...args)


// RCTVirtualText is being used for LogBox while RCTText is being used for normal text
if (origin.type === 'RCTVirtualText') {
return origin
}


const children = origin.props.children
if (typeof children === 'object') {
return React.cloneElement(origin, {
children: React.cloneElement(children, {
style: [yourStyle, children.props.style]
})
})
}


return React.cloneElement(origin, {
style: [yourStyle, origin.props.style]
})
}
}