Как установить семейство шрифтов по умолчанию в 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 вместе с любыми другими предоставленными вами реквизитами / стилями.

Ajackster
источник
Идиоматический метод использования компонентного состава кажется лучшим выбором, хотя это крутой прием.
Дэниел Литтл
Когда компонент 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 })

AJA
источник
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>
...
anni
источник
@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]];
  ....
}

Выполнено.

Garrettmac
источник
Лучший подход, но не работает, что-нибудь связанное с последним обновлением RN 0.57?
user2976753
1

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

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

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

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

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

Хушбу Тахир
источник
1

Добавить

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

в package.json том запуститьreact-native link

Санджиб Суна
источник
1

Установить в package.json

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

И ссылка на реакцию на родную ссылку

амин Мохаммади
источник