¿Cómo configurar la familia de fuentes predeterminada en React Native?


98

¿Existe un equivalente a este CSS en React Native, de modo que la aplicación use la misma fuente en todas partes?

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

Aplicarlo manualmente en cada nodo de texto parece demasiado complicado.


1
¿Tiene alguna respuesta perfecta para esta pregunta? No quiero llamar a ningún styles.text ni nada por el estilo.
MD Ashik

Respuestas:


70

La forma recomendada es crear su propio componente, como MyAppText. MyAppText sería un componente simple que representa un componente de texto usando su estilo universal y puede pasar por otros accesorios, etc.

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


2
Gracias, eso es exactamente lo que necesitaba. Parece que todavía no entendí el enfoque de componentes lo suficientemente profundo :)
Dagobert Renouf

2
Una cosa que no está muy clara en los documentos es cómo pasar las propiedades de su componente y respetar los estilos de su componente. Puede hacerlo así: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar

1
@NeilSarkar Un problema con ese ejemplo esencial es que el estilo se genera en el constructor. Como resultado, si cambia el accesorio de estilo, querrá que se vuelva a renderizar, pero en este caso no lo hará. Debe manejarse en render()lugar del constructor. Usar ganchos con useMemotambién podría ayudar si la eficiencia es importante. Alternativamente, si desea mantenerlo en el constructor, es importante agregar una componentDidUpdatelógica que se actualice this.stylecuando el componente se actualice debido a un cambio de estilo.
Fernando Rojo

buen punto, gracias! Parece que alguien también agregó una versión refactorizada a la esencia que combina los estilos en el método de renderizado (de un componente puro, en su caso)
Neil Sarkar

58

Recientemente se creó un módulo de nodo que resuelve este problema para que no tenga que crear otro componente .

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

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

La documentación indica que en su componente de mayor orden, importe la setCustomTextfunción como tal.

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

Luego, cree el estilo / accesorios personalizados que desee para el Textcomponente react-native . En su caso, le gustaría que fontFamily funcione en todos los Textcomponentes.

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

Llame a la setCustomTextfunción y pase sus accesorios / estilos a la función.

setCustomText(customTextProps);

Y luego todos los Textcomponentes de react-native tendrán su fontFamily declarada junto con cualquier otro accesorio / estilo que proporcione.


El método idiomático para usar la composición de componentes parece una mejor opción, aunque este es un truco genial.
Daniel Little

Cuando el componente Texto no admite el cambio de fuentes predeterminadas, esta solución se vuelve mucho mejor. Preferiría agregar un control global en un solo lugar y usar los componentes nativos que crear un componente contenedor para cada detalle que brindan las verdaderas aplicaciones nativas.
mienaikoe

Dudé entre las 2 soluciones anteriores, de hecho, odio instalar complementos no oficiales porque react-native sigue cambiando, pero finalmente elijo esta ya que realmente me puede ahorrar una gran cantidad de tiempo. ¡Gracias!
Zhang Buzz

¿Entonces necesito llamar <Text style={styles.text}>? No es una solución perfecta como esa, ¿ body {font-family: 'Open Sans';} tiene alguna solución de actualización?
MD Ashik

1
No, no es necesario que lo haga Text style={styles.text}>. Solo necesita declarar sus accesorios personalizados en algún lugar de su aplicación y se aplicará a todos sus componentes de texto. Es muy similar abody {font-family: ....}
Ajackster

31

Para React Native 0.56.0+, compruebe si defaultProps se define primero:

Text.defaultProps = Text.defaultProps || {}

Luego añade:

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

Agregue lo anterior en el constructor del archivo App.js (o cualquier componente raíz que tenga).

Para anular el estilo, puede crear un objeto de estilo y difundirlo y luego agregar su estilo adicional (por ejemplo { ...baseStyle, fontSize: 16 })


4
Tal vez defaultPropsno existía cuando se escribieron todas las demás respuestas, pero esta parece ser la forma de hacerlo ahora.
freeall

4
Desafortunadamente, no funcionará si anulamos la styleutilería, digamos, para modificar estilos de Textcomponentes particulares
Amerzilla

Es cierto, pero puede evitar esto, cree el estilo común como un objeto y cuando quiera alguna fuente personalizada simplemente pase al componente una matriz que contenga ese objeto + yourNewStyleObject @Amerzilla
AJA

1
Ahí hay un problema. Si alguien define el styleaccesorio en el componente Texto, se reemplazará la fuente predeterminada.
Broda Noel

2
es 2019 y está funcionando perfectamente. solo recuerda que en Android no puedes usar "-" en los nombres de archivo. defina los nombres de sus archivos de fuentes, algo como font_name.ttf.
MRSafari

23

Puede anular el comportamiento de Text agregando esto en cualquiera de sus componentes usando 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]
    });
};

Editar: desde React Native 0.56, Text.prototypeya no funciona. Necesitas eliminar .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
Esa es una gran solución, pero tienes que cambiar: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] De lo contrario, anulará el estilo personalizado establecido en el componente
Iaconis Simone

1
Funcionó mejor. Text.prototype.render ya no funciona, ¡Text.render sí!
Kira

1
¿Cómo evitar que los iconos hereden los mismos?
mafia

1
Estoy de acuerdo con @IaconisSimone El mejor enfoque para establecer fontFamily y para asegurarme de no anular los estilos personalizados
dczii

1
Este es el camino a seguir
Witalo Benicio

15

Añadir

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

en package.json luego correreact-native link


14

Con React-Native 0.56, el método de cambio anterior Text.prototype.renderya no funciona, por lo que debe usar su propio componente, ¡que se puede hacer en una línea!

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 Ahora lo hará con ganchos y useRef. reactjs.org/docs/hooks-reference.html#useref
Christopher Reid

11

Agregue esta función a su Appcomponente raíz y luego ejecútela desde su constructor después de agregar su fuente siguiendo estas instrucciones. 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;
            }
        };
    }
}

Esto es exactamente lo que estaba buscando, no quería instalar nada más.
zevy_boy

Si mis app.js consiste principalmente en const App = StackNavigator({...})y export default Appdónde exactamente iba a colocar este código ya que no creo que pueda utilizar un constructor aquí?
kojow7

He agregado mi propia pregunta aquí: stackoverflow.com/questions/50081042/…
kojow7

¿Por qué constructor sobre componentDidMount?
Dror Bar

2

Súper tarde para este hilo pero aquí va.

TLDR; Agregue el siguiente bloque en suAppDelegate.m

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

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

Tutorial de todo el flujo.

Algunas formas en las que puede hacer esto además de usar un complemento como, react-native-global-propsasí que lo guiaré paso a paso.

Añadiendo fuentes a las plataformas.

Cómo agregar la fuente al proyecto IOS

Primero, creemos una ubicación para nuestros activos. Hagamos el siguiente directorio en nuestra raíz.

''

ios/
static/
       fonts/

''

Ahora agreguemos un NPM "React Native" en nuestro package.json

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

Ahora podemos ejecutar "react-native link" para agregar nuestros activos a nuestras aplicaciones nativas.

Verificando o haciendo manualmente.

Eso debería agregar sus nombres de fuente en los proyectos .plist (para que los usuarios del código VS corran code ios/*/Info.plistpara confirmar)

Aquí supongamos que Verlages la fuente que agregó, debería verse así:

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

Ahora que los asignó, ahora asegurémonos de que estén realmente allí y se estén cargando (así es también como lo haría manualmente).

Vaya a "Build Phase" > "Copy Bundler Resource", si no funcionó, agregará manualmente debajo de ellos aquí.

1_uuz0__3kx2vvguz37bhvya

Obtener nombres de fuentes (reconocidos por XCode)

Primero abra sus registros de XCode, como:

XXXX

Luego puede agregar el siguiente bloque en su AppDelegate.mpara registrar los nombres de las fuentes y la familia de fuentes.

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


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

  ...
}

Una vez que ejecutes deberías encontrar tus fuentes si se cargan correctamente, aquí encontramos las nuestras en registros 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

Así que ahora sabemos que cargó la Verlagfamilia y son las fuentes dentro de esa familia.

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

Estos son ahora los nombres sensibles a mayúsculas y minúsculas que podemos usar en nuestra familia de fuentes que podemos usar en nuestra aplicación nativa de reacción.

Got -'em ahora establece la fuente predeterminada.

Luego, para establecer una fuente predeterminada para agregar su nombre de familia de fuentes en su AppDelegate.mcon esta línea

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

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

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

Hecho.


El mejor enfoque, pero no funciona, ¿algo relacionado con la última actualización de RN 0.57?
user2976753

2

Establecer en package.json

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

Y vincular el vínculo nativo de reacción


1

Eso funciona para mí: Agregar fuente personalizada en React Native

descargue sus fuentes y colóquelas en la carpeta assets / fonts, agregue esta línea en package.json

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

luego abra la terminal y ejecute este comando: react-native link

Ahora estás listo para comenzar. Para un paso más detallado. visite el enlace mencionado anteriormente

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.