Как установить семейство шрифтов по умолчанию в React Native?
Есть ли эквивалент в этом CSS в React Native, чтобы приложение везде использовало один и тот же шрифт?
body {
font-family: 'Open Sans';
}
Применение его вручную на каждом текстовом узле кажется слишком сложным.
16 ответов
Рекомендуемый способ - создать собственный компонент, такой как MyAppText. MyAppText будет простым компонентом, который визуализирует компонент Text с использованием вашего универсального стиля и может проходить через другие объекты и т. Д.
Недавно был создан модуль узла, который решает эту проблему, поэтому вам не нужно создавать другой компонент.
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.defaultProps.style = { fontFamily: 'some-font' }
в конструкторе файла App.js (или любого вашего корневого компонента).
Вы можете переопределить поведение Text, добавив его в любой из ваших компонентов, используя Text:
let oldRender = Text.prototype.render;
Text.prototype.render = function (...args) {
let origin = oldRender.call(this, ...args);
return React.cloneElement(origin, {
style: [origin.props.style, {color: 'red', fontFamily: 'Arial'}]
});
};
Изменить: начиная с 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: [origin.props.style, {color: 'red', fontFamily: 'Arial'}]
});
};
С 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>
...
Добавить
"rnpm": {
"assets": [
"./assets/fonts/"
]
}
в package.json
затем беги react-native link
Добавьте эту функцию в свой корень 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;
}
};
}
}
Супер поздно в этой теме, но здесь идет.
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/
`` `
Теперь давайте добавим NPM "React Native" в наш package.json
"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"
, Если это не сработало, вы можете вручную добавить их здесь.
Получить имена шрифтов (распознается XCode)
Сначала откройте ваши журналы XCode, например:
Затем вы можете добавить следующий блок в свой 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-native-global-props
библиотека не обновлялась с 2018 года.
Я нашел этот альтернативный пакет:react-native-simple-default-props
https://www.npmjs.com/package/react-native-simple-default-props
Точно следовал документации, и все заработало отлично после того, как я несколько часов застрял в поиске наилучшего способа сделать это. Надеюсь, это кому-то поможет.
Установить в package.json
"rnpm": {
"assets": [
"./assets/fonts/"
]
}
И ссылка на реакцию на родную ссылку
Для Android это работает для меня.
Создайте папку с именем шрифт внутри
android\app\src\main\res\
Вставьте файл font.ttf/.otf в папку со шрифтами. Убедитесь, что имя шрифта состоит только из строчных букв и подчеркивания.
например:- rubik_regular.ttf
Добавьте строку ниже в
android\app\src\main\res\values\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>
Чтобы иметь стиль шрифта по умолчанию без стиля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]
})
}
}
Это работает для меня:добавить собственный шрифт в React Native
загрузите свои шрифты и поместите их в папку assets/fonts, добавьте эту строку в package.json
"rnpm": {
"assets": ["assets/fonts/Sarpanch"]}
затем откройте терминал и запустите эту команду: response-native link
Теперь ты в порядке. Для более подробного шага. перейдите по ссылке выше
Для React Native версии ≥ 0.60 в корневом файле создайте файл с именем
react-native.config.js
и поместите следующее, затем просто запустите
react-native link
module.exports = {
assets: ["./assets/fonts"]
}
Этот ответ работал у меня, когда я использовал
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 ]
});
};
Обратите внимание, что prop может быть
object
, например, это может быть
LogBoxMessage
составная часть. Но тип поддержки обычных текстов, отображаемых на экране, является типом
string
.
Вы можете использовать рекурсивную функцию для применения
fontFamily
к
children
Вы можете попробовать создать тему для своего приложения, вы можете использовать собственную библиотеку пользовательского интерфейса React, такую как Nativebase, для достижения того, что вы ищете, а также вы можете создать свою собственную тему или компонент.