Как установить семейство шрифтов по умолчанию в React Native?


100

Есть ли в React Native эквивалент этому CSS, чтобы приложение везде использовало один и тот же шрифт?

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

Применение его вручную к каждому текстовому узлу кажется чрезмерно сложным.


1
Есть ли идеальный ответ на этот вопрос ??? Я не хочу называть стили .text или что-то подобное.
MD

Ответы:


70

Рекомендуемый способ - создать собственный компонент, например MyAppText. MyAppText будет простым компонентом, который отображает компонент Text с использованием вашего универсального стиля и может передавать другие свойства и т. Д.

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


2
Спасибо, это именно то, что мне нужно. Похоже, я еще недостаточно глубоко понял компонентный подход :)
Дагоберт Ренуф

2
Одна вещь, которая не очень ясна из документации, - это то, как передавать свойства в вашем компоненте и соблюдать стили в вашем компоненте. Вы можете сделать это так: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Нил Саркар

1
@NeilSarkar Одна из проблем с этим главным примером заключается в том, что стиль создается в конструкторе. В результате, если свойство стиля изменится, вы захотите его повторно отрисовать, но в данном случае этого не произойдет. Он должен обрабатываться render()вместо конструктора. Использование крючков с useMemoтакже может помочь, если важна эффективность. В качестве альтернативы, если вы хотите сохранить его в конструкторе, важно добавить componentDidUpdateлогику, которая обновляется, this.styleкогда компонент обновляется из-за изменения свойства стиля.
Фернандо Рохо,

хороший момент, спасибо! похоже, что кто-то добавил к сути отредактированную версию, которая объединяет стили в методе рендеринга (чистого компонента, в их случае)
Нил Саркар

59

Недавно был создан модуль узла, который решает эту проблему, поэтому вам не нужно создавать другой компонент .

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

И тогда все Textкомпоненты, поддерживающие реакцию, будут иметь ваше объявленное fontFamily вместе с любыми другими предоставленными вами реквизитами / стилями.


Идиоматический метод использования компонентного состава кажется лучшим выбором, хотя это крутой прием.
Дэниел Литтл

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

Я колебался между двумя вышеперечисленными решениями, на самом деле я ненавижу устанавливать неофициальные плагины, потому что сам response-native продолжает меняться, но в конце концов я выбрал это, так как оно действительно может сэкономить мне огромное количество времени. Благодарность!
Чжан Базз

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

1
Нет, не нужно Text style={styles.text}>. Вам просто нужно объявить свои собственные реквизиты где-нибудь в вашем приложении, и они будут применены ко всем вашим текстовым компонентам. Это очень похоже наbody {font-family: ....}
Ajackster

32

Для 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компонентов
Amerzilla

Верно, но вы можете обойти это, создав общий стиль как объект, и, когда вам понадобится какой-то настраиваемый шрифт, просто передайте компоненту массив, содержащий этот объект + yourNewStyleObject @Amerzilla
AJA

1
Там проблема. Если кто-то затем определит styleопору в компоненте Text, шрифт по умолчанию будет заменен.
Broda Noel

3
Сейчас 2019 год, и он работает отлично. просто помните, что в Android нельзя использовать "-" в именах файлов. определите имена файлов шрифтов, например, font_name.ttf.
MRSafari

24

Вы можете переопределить поведение 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
как избежать наследования значков одинаковыми?
Venkat

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. reactjs.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

Супер поздно к этой теме, но вот оно.

TL; DR; Добавьте следующий блок в свой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"ссылке, если это не сработало, вы вручную добавите их сюда.

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

Теперь это имена с учетом регистра, которые мы можем использовать в нашем семействе шрифтов, которое мы можем использовать в нашем родном приложении для реакции.

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

1

Это работает для меня: добавить собственный шрифт в React Native

загрузите свои шрифты и поместите их в папку assets / fonts, добавьте эту строку в package.json

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

затем откройте терминал и запустите эту команду: response-native link

Теперь ты в порядке. Для более подробного шага. перейдите по ссылке выше



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.