Como definir a família de fontes padrão no React Native?

98

Existe um equivalente a este CSS no React Native, de modo que o aplicativo use a mesma fonte em todos os lugares?

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

Aplicá-lo manualmente em cada nó de Texto parece excessivamente complicado.

Dagobert Renouf
fonte
1
Tem alguma resposta perfeita para esta pergunta ?? Não quero chamar nenhum styles.text ou qualquer coisa assim.
MD Ashik

Respostas:

70

A maneira recomendada é criar seu próprio componente, como MyAppText. MyAppText seria um componente simples que renderiza um componente de texto usando seu estilo universal e pode passar por outros adereços, etc.

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

David E. Chen
fonte
2
Obrigado, era exatamente o que eu precisava. Parece que ainda não entendi a abordagem do componente a fundo o suficiente :)
Dagobert Renouf
2
Uma coisa que não está muito clara nos documentos é como passar pelas propriedades em seu componente e respeitar os estilos em seu componente. Você pode fazer isso assim: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar
1
@NeilSarkar Um problema com esse exemplo essencial é que o estilo é gerado no construtor. Como resultado, se o estilo de sustentação mudar, você gostaria que ele fosse renderizado novamente, mas neste caso não será. Ele deve ser tratado em render()vez do construtor. Usar ganchos com useMemotambém pode ajudar se a eficiência for importante. Alternativamente, se você quiser mantê-lo no construtor, é importante adicionar uma componentDidUpdatelógica que atualiza this.stylequando o componente é atualizado devido a uma mudança de prop de estilo.
Fernando Rojo
bom ponto, obrigado! parece que alguém adicionou uma versão refatorada à essência também que combina os estilos no método de renderização (de um componente puro, no caso deles)
Neil Sarkar
58

Recentemente, foi feito um módulo de nó que resolve esse problema para que você não precise criar outro componente .

https://github.com/Ajackster/react-native-global-props

https://www.npmjs.com/package/react-native-global-props

A documentação afirma que em seu componente de ordem superior, importe a setCustomTextfunção como tal.

import { setCustomText } from 'react-native-global-props';

Em seguida, crie o estilo / adereços personalizados que deseja para o Textcomponente react-native . No seu caso, você gostaria que o fontFamily trabalhasse em todos os Textcomponentes.

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

Chame a setCustomTextfunção e passe seus adereços / estilos para a função.

setCustomText(customTextProps);

E então todos os Textcomponentes do react -native terão sua fontFamily declarada junto com quaisquer outros adereços / estilos que você fornecer.

Ajackster
fonte
O método idiomático para usar a composição de componentes parece uma escolha melhor, embora este seja um hack legal.
Daniel Little de
Quando o componente Texto não oferece suporte à alteração das fontes padrão imediatamente, essa solução se torna muito melhor. Eu preferiria adicionar um controle global em um lugar e usar os componentes nativos do que fazer um componente wrapper para cada detalhe que os aplicativos nativos verdadeiros fornecem.
mienaikoe
Hesitei entre as 2 soluções acima, na verdade, odeio instalar plug-ins não oficiais porque o próprio react-native continua a mudar, mas finalmente escolhi esta porque pode realmente me economizar muito tempo. Obrigado!
Zhang Buzz
SO eu preciso ligar <Text style={styles.text}>?? Não é uma solução perfeita como se body {font-family: 'Open Sans';} tivesse alguma solução de atualização ??
MD Ashik
1
Não, você não precisa fazer Text style={styles.text}>. Você só precisa declarar seus adereços personalizados em algum lugar do seu aplicativo e eles serão aplicados a todos os seus componentes de texto. É muito semelhante abody {font-family: ....}
Ajackster
31

Para React Native 0.56.0+, verifique se defaultProps é definido primeiro:

Text.defaultProps = Text.defaultProps || {}

Em seguida, adicione:

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

Adicione o acima no construtor do arquivo App.js (ou qualquer componente raiz que você tenha).

Para substituir o estilo, você pode criar um objeto de estilo e espalhá-lo, em seguida, adicionar seu estilo adicional (por exemplo { ...baseStyle, fontSize: 16 })

AJA
fonte
4
Talvez defaultPropsnão existisse quando todas as outras respostas foram escritas, mas essa parece ser a maneira de fazer isso agora.
freeall
4
Infelizmente, não funcionará se substituirmos o styleadereço, digamos, para ajustar estilos de Textcomponentes específicos
Amerzilla
Verdadeiro, mas você pode contornar isso, crie o estilo comum como um objeto e sempre que quiser alguma fonte personalizada apenas passe para o componente um array que contenha esse objeto + seuObjetoNovoEstilo @Amerzilla
AJA
1
Existe um problema aí. Se alguém definir o styleprop no componente Texto, a fonte padrão será substituída.
Broda Noel de
2
é 2019 e está funcionando perfeitamente. lembre-se de que no android você não pode usar "-" nos nomes dos arquivos. defina seus nomes de arquivo de fonte como font_name.ttf.
MRSafari
23

Você pode substituir o comportamento de Texto adicionando-o a qualquer um dos seus componentes usando Texto:

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

Edit: desde React Native 0,56, Text.prototypenão está mais funcionando. Você precisa remover .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]
    });
};
Floris M
fonte
4
Essa é uma ótima solução, mas você precisa mudar: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] Caso contrário, você substituirá o estilo personalizado definido no componente
Iaconis Simone
1
Funcionou melhor. Text.prototype.render não funciona mais, Text.render sim!
Kira
1
como evitar que os ícones herdem o mesmo?
mob
1
Eu concordo com @IaconisSimone Melhor abordagem para definir fontFamily e ter certeza de não substituir estilos personalizados
dczii
1
Este é o caminho a seguir
Witalo Benicio
15

Adicionar

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

em package.json seguida, corrareact-native link

Sanjib Suna
fonte
14

Com o React-Native 0,56, o método de alteração acima Text.prototype.rendernão funciona mais, então você deve usar seu próprio componente, o que pode ser feito em uma linha!

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>
...
bobby
fonte
@FancyJohn Agora será com ganchos e useRef. reactjs.org/docs/hooks-reference.html#useref
Christopher Reid
11

Adicione esta função ao seu Appcomponente raiz e execute-a a partir do seu construtor após adicionar a sua fonte usando estas instruções. 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;
            }
        };
    }
}
Roubar
fonte
Isso é exatamente o que eu procurava, não queria instalar mais nada.
zevy_boy
Se meu App.js consistir principalmente em const App = StackNavigator({...})e export default Apponde exatamente eu colocaria esse código, pois não acho que posso usar um construtor aqui?
kojow7
Eu adicionei minha própria pergunta aqui: stackoverflow.com/questions/50081042/…
kojow7
Por que construtor em vez de componentDidMount?
Dror Bar
2

Muito tarde para este tópico, mas aqui vai.

TLDR; Adicione o seguinte bloco em seuAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 ....
    // HERE: replace "Verlag" with your font
  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

Passo a passo de todo o fluxo.

Algumas maneiras de fazer isso além de usar um plug-in como, react-native-global-propspor exemplo, vou acompanhá-lo passo a passo.

Adicionando fontes às plataformas.

Como adicionar a fonte ao projeto IOS

Primeiro, vamos criar um local para nossos ativos. Vamos fazer o seguinte diretório em nossa raiz.

`` `

ios/
static/
       fonts/

`` `

Agora vamos adicionar um NPM "React Native" em nosso package.json

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

Agora podemos executar "link nativo de reação" para adicionar nossos ativos aos nossos aplicativos nativos.

Verificando ou fazendo manualmente.

Isso deve adicionar os nomes das fontes aos projetos .plist (para os usuários do código VS, execute code ios/*/Info.plistpara confirmar)

Vamos supor que Verlagseja a fonte que você adicionou, ela deve ser semelhante a esta:

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

Agora que você os mapeou, vamos verificar se eles estão realmente lá e sendo carregados (também é assim que você faria manualmente).

Vá para "Build Phase" > "Copy Bundler Resource", Se não funcionar, você adicionará manualmente abaixo deles aqui.

1_uuz0__3kx2vvguz37bhvya

Obter nomes de fontes (reconhecido por XCode)

Primeiro, abra seus logs do XCode, como:

XXXX

Em seguida, você pode adicionar o seguinte bloco em seu AppDelegate.mpara registrar os nomes das fontes e da família de fontes.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    .....


  for (NSString* family in [UIFont familyNames])
  {
    NSLog(@"%@", family);
    for (NSString* name in [UIFont fontNamesForFamilyName: family])
    {
      NSLog(@" %@", name);
    }
  }

  ...
}

Depois de executar, você deve encontrar suas fontes, se carregadas corretamente, aqui encontramos as nossas em logs como este:

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

Agora sabemos que carregou a Verlagfamília e são as fontes dentro dessa família

  • Verlag-Book
  • Verlag-BlackItalic
  • Verlag-BoldItalic
  • Verlag-XLight
  • Verlag-Bold
  • Verlag-Black
  • Verlag-XLightItalic
  • Verlag-LightItalic
  • Verlag-BookItalic
  • Verlag-Light

Agora, esses são os nomes com distinção entre maiúsculas e minúsculas que podemos usar em nossa família de fontes e em nosso aplicativo nativo react.

Agora eles definem a fonte padrão.

Em seguida, para definir uma fonte padrão para adicionar o nome da família da fonte em seu AppDelegate.mcom esta linha

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 ....
    // ADD THIS LINE (replace "Verlag" with your font)

  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

Feito.

Garrettmac
fonte
A melhor abordagem, mas não está funcionando, alguma coisa relacionada a ultima atualização do RN 0,57?
user2976753
2

Definido em package.json

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

E link link react-nativo

puc12
fonte
1

Isso funciona para mim: adicione uma fonte personalizada no React Native

baixe suas fontes e coloque-as na pasta assets / fonts, adicione esta linha em package.json

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

em seguida, abra o terminal e execute este comando: link react-native

Agora você está pronto para ir. Para uma etapa mais detalhada. visite o link acima mencionado

Khushboo Tahir
fonte