Як встановити сімейство шрифтів за замовчуванням у React Native?


98

Чи існує еквівалент цього CSS у React Native, щоб програма використовувала однаковий шрифт скрізь?

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

Застосування його вручну на кожному вузлі Text здається надто складним.


1
Є ідеальна відповідь на це питання ??? Я не хочу називати стилі. Text або щось подібне.
MD Ashik,

Відповіді:


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
Ніл Саркар

1
@NeilSarkar Однією з проблем цього прикладу є те, що стиль генерується в конструкторі. Як результат, якщо зміна пропису стилю, ви б хотіли, щоб вона рендерилась, але в цьому випадку це не буде. Його слід обробляти render()замість конструктора. Використання гачків useMemoтакож може допомогти, якщо ефективність важлива. Крім того, якщо ви хочете зберегти його в конструкторі, важливо додати componentDidUpdateлогіку, яка оновлюється, this.styleколи компонент оновлюється через зміну властивості стилю.
Фернандо Рохо

хороший момент, дякую! схоже на те, що хтось також додав до суті реконструйовану версію, яка поєднує стилі в методі візуалізації (у чистому випадку, у їхньому випадку)
Ніл Саркар,

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

Потім створіть власний стиль / реквізит, який ви хочете реагувати на рідний Textкомпонент. У вашому випадку ви хотіли б, щоб fontFamily працював над кожним Textкомпонентом.

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

Викличте setCustomTextфункцію та передайте свої функції / стилі у функцію.

setCustomText(customTextProps);

І тоді всі реакційніText компоненти матимуть ваш оголошений fontFamily разом з будь-яким іншим реквізитом / стилем, який ви надаєте.


Ідіоматичний метод використання компонентної композиції здається кращим вибором, хоча це крутий хак.
Деніел Літтл

Коли компонент Text не підтримує зміну шрифтів за замовчуванням, це рішення стає набагато кращим. Я б набагато краще додав глобальний контроль в одному місці і використовував власні компоненти, ніж створював компонент-обгортку для кожної деталі, яку надають справжні рідні програми.
mienaikoe

Я вагався між вищезазначеними 2 рішеннями, насправді я ненавиджу встановлювати неофіційні плагіни, тому що сама реакція-рідна продовжує змінюватися, але, нарешті, я вибираю саме цю, оскільки це дійсно може заощадити мені величезну кількість часу. Дякую!
Чжан Базз,

ТАК мені потрібно дзвонити <Text style={styles.text}>?? Це не ідеальне рішення, подібне тому body {font-family: 'Open Sans';} , якесь рішення для оновлення ??
MD Ashik,

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цього не існувало, коли були написані всі інші відповіді, але, схоже, це спосіб зробити це зараз.
вільне падіння

4
На жаль, це не буде працювати, якщо ми styleскасуємо, наприклад, налаштування стилів певних Textкомпонентів
Amerzilla

Правда, але ви можете обійти це, створити загальний стиль як об’єкт, і коли захочете, якийсь власний шрифт просто передайте компоненту масив, що містить цей об’єкт + вашNewStyleObject @Amerzilla
AJA

1
Там проблема. Якщо хтось потім визначить styleпроп у компоненті Текст, шрифт за замовчуванням буде замінено.
Брода Ноель,

2
це 2019 рік, і він працює ідеально. просто пам’ятайте, що в android ви не можете використовувати "-" в іменах файлів. визначте назви файлів шрифтів щось на зразок font_name.ttf.
MRSafari,

23

Ви можете замінити поведінку тексту, додавши це до будь-якого з компонентів за допомогою тексту:

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
як уникнути значків, що успадковують те саме?
моб

1
Я погоджуюсь з @IaconisSimone Найкращий підхід до встановлення fontFamily та до того, щоб не перевизначати власні стилі
dczii,

1
Це такий шлях
Вітало Бенісіо


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 Тепер буде з гачками і useRef. responsejs.org/docs/hooks-reference.html#useref
Крістофер Рід

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,

Я додав своє питання тут: 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/

``

Тепер додамо NPM "React Native" у наш пакет.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", якщо це не спрацювало, ви вручну додасте їх тут.

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]];
  ....
}

Готово.


Найкращий підхід, але не працює, щось пов’язане з останнім оновленням RN 0.57?
user2976753

2

Встановити в package.json

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

І посилання реакція-рідне посилання


1

Це працює для мене: додайте власний шрифт у React Native

завантажте шрифти та розмістіть їх у папці resources / fonts, додайте цей рядок у package.json

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

потім відкрийте термінал і запустіть цю команду: response-native link

Тепер вам добре йти. Для більш детального кроку. відвідайте вищезгадане посилання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.