Comment définir la famille de polices par défaut dans React Native?

98

Existe-t-il un équivalent à ce CSS dans React Native, afin que l'application utilise la même police partout?

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

Son application manuelle sur chaque nœud de texte semble trop compliquée.

Dagobert Renouf
la source
1
Avez-vous une réponse parfaite pour cette question ??? Je ne veux appeler aucun style.text ou quoi que ce soit de ce genre.
MD Ashik du

Réponses:

70

La méthode recommandée consiste à créer votre propre composant, tel que MyAppText. MyAppText serait un composant simple qui restitue un composant de texte en utilisant votre style universel et peut passer par d'autres accessoires, etc.

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

David E. Chen
la source
2
Merci, c'est exactement ce dont j'avais besoin. On dirait que je n'ai pas encore suffisamment compris l'approche des composants :)
Dagobert Renouf
2
Une chose qui n'est pas très claire dans la documentation est de savoir comment passer les propriétés de votre composant et respecter les styles de votre composant. Vous pouvez le faire comme ceci: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar
1
@NeilSarkar Un problème avec cet exemple essentiel est que le style est généré dans le constructeur. En conséquence, si l'accessoire de style change, vous voudrez qu'il soit à nouveau rendu, mais dans ce cas, il ne le sera pas. Il doit être géré au render()lieu du constructeur. L'utilisation de crochets avec useMemopeut également aider si l'efficacité est importante. Sinon, si vous souhaitez le conserver dans le constructeur, il est important d'ajouter une componentDidUpdatelogique qui se met this.styleà jour lorsque le composant est mis à jour en raison d'un changement d'accessoire de style.
Fernando Rojo le
bon point, merci! on dirait que quelqu'un a ajouté une version refactorisée à l'essentiel qui combine les styles de la méthode de rendu (d'un composant pur, dans leur cas)
Neil Sarkar
58

Il y a eu récemment un module de nœud qui a été créé qui résout ce problème afin que vous n'ayez pas à créer un autre composant .

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

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

La documentation indique que dans votre composant d'ordre le plus élevé, importez la setCustomTextfonction comme ceci.

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

Ensuite, créez le style / accessoires personnalisés que vous souhaitez pour le Textcomposant natif de réaction . Dans votre cas, vous aimeriez que fontFamily travaille sur chaque Textcomposant.

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

Appelez la setCustomTextfonction et passez vos accessoires / styles dans la fonction.

setCustomText(customTextProps);

Et puis tous les Textcomposants natifs de réaction auront votre fontFamily déclarée avec tous les autres accessoires / styles que vous fournissez.

Ajackster
la source
La méthode idiomatique pour utiliser la composition des composants semble être un meilleur choix, bien que ce soit un hack cool.
Daniel Little
Lorsque le composant Texte ne prend pas en charge la modification des polices par défaut hors de la boîte, cette solution devient bien meilleure. Je préfère de loin ajouter un contrôle global en un seul endroit et utiliser les composants natifs plutôt que de créer un composant wrapper pour chaque détail fourni par les vraies applications natives.
mienaikoe
J'ai hésité entre les 2 solutions ci-dessus, en fait je déteste installer des plugins non officiels car le react-native lui-même continue de changer, mais finalement je choisis celle-ci car elle peut vraiment me faire gagner énormément de temps. Merci!
Zhang Buzz
Alors j'ai besoin d'appeler <Text style={styles.text}>?? Ce n'est pas une solution parfaite comme celle qui body {font-family: 'Open Sans';} a une solution de mise à jour ??
MD Ashik du
1
Non, vous n'avez pas besoin de faire Text style={styles.text}>. Il vous suffit de déclarer vos accessoires personnalisés quelque part dans votre application et ils seront appliqués à tous vos composants Text. C'est très similaire àbody {font-family: ....}
Ajackster
31

Pour React Native 0.56.0+, vérifiez si defaultProps est défini en premier:

Text.defaultProps = Text.defaultProps || {}

Puis ajouter:

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

Ajoutez ce qui précède dans le constructeur du fichier App.js (ou de tout composant racine que vous avez).

Afin de remplacer le style, vous pouvez créer un objet de style et le diffuser puis ajouter votre style supplémentaire (par exemple { ...baseStyle, fontSize: 16 })

AJA
la source
4
Peut-être que cela defaultPropsn'existait pas lorsque toutes les autres réponses ont été écrites, mais cela semble être la façon de le faire maintenant.
freeall
4
Malheureusement, cela ne fonctionnera pas si nous remplaçons les styleaccessoires, par exemple, pour modifier les styles de Textcomposants particuliers
Amerzilla
C'est vrai, mais vous pouvez contourner cela, créer le style commun en tant qu'objet et chaque fois que vous voulez une police personnalisée, passez simplement au composant un tableau qui contient cet objet + yourNewStyleObject @Amerzilla
AJA
1
Il y a là un problème. Si quelqu'un définit ensuite l' styleaccessoire dans le composant Texte, la police par défaut va être remplacée.
Broda Noel
2
c'est 2019 et ça marche parfaitement. rappelez-vous que dans Android, vous ne pouvez pas utiliser "-" dans les noms de fichiers. définissez vos noms de fichiers de polices quelque chose comme font_name.ttf.
MRSafari
23

Vous pouvez remplacer le comportement du texte en l'ajoutant dans l'un de vos composants à l'aide de 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]
    });
};

Edit: depuis React Native 0.56, Text.prototypene fonctionne plus. Vous devez supprimer .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
la source
4
C'est une excellente solution mais vous devez changer: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] Sinon, vous remplacerez le style personnalisé défini dans le composant
Iaconis Simone
1
A fonctionné le mieux. Text.prototype.render ne fonctionne plus, Text.render le fait!
Kira
1
comment éviter que les icônes héritent du même?
mob
1
Je suis d'accord avec @IaconisSimone La meilleure approche pour définir fontFamily et pour être sûr de ne pas remplacer les styles personnalisés
dczii
1
C'est la voie à suivre
Witalo Benicio
15

Ajouter

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

dans package.json puis courirreact-native link

Sanjib Suna
la source
14

Avec React-Native 0.56, la méthode de changement ci-dessus Text.prototype.renderne fonctionne plus, vous devez donc utiliser votre propre composant, ce qui peut être fait en une seule ligne!

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>
...
policier
la source
@FancyJohn Il le sera maintenant avec des crochets et useRef. reactjs.org/docs/hooks-reference.html#useref
Christopher Reid
11

Ajoutez cette fonction à votre Appcomposant racine , puis exécutez-la à partir de votre constructeur après avoir ajouté votre police en suivant ces instructions. 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;
            }
        };
    }
}
Rob
la source
C'est exactement ce que je cherchais, je ne voulais plus rien installer.
zevy_boy
Si mon App.js consiste principalement en const App = StackNavigator({...})et export default Appoù placer exactement ce code car je ne pense pas que je peux utiliser un constructeur ici?
kojow7
J'ai ajouté ma propre question ici: stackoverflow.com/questions/50081042/…
kojow7
Pourquoi constructeur sur componentDidMount?
Dror Bar
2

Super tard dans ce fil mais voilà.

TLDR; Ajoutez le bloc suivant dans votreAppDelegate.m

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

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

Procédure pas à pas de tout le flux.

Quelques façons de le faire en dehors de l'utilisation d'un plugin comme react-native-global-propsje vais vous guider étape par étape.

Ajout de polices aux plates-formes.

Comment ajouter la police au projet IOS

Commençons par créer un emplacement pour nos actifs. Créons le répertoire suivant à notre racine.

''

ios/
static/
       fonts/

''

Ajoutons maintenant un NPM "React Native" dans notre package.json

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

Nous pouvons maintenant exécuter un "lien de réaction natif" pour ajouter nos ressources à nos applications natives.

Vérification ou exécution manuelle.

Cela devrait ajouter vos noms de police dans les projets .plist (pour les utilisateurs de code VS, exécutez code ios/*/Info.plistpour confirmer)

Supposons ici que Verlagla police que vous avez ajoutée ressemble à ceci:

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

Maintenant que vous les avez mappés, nous allons maintenant nous assurer qu'ils sont réellement là et en cours de chargement (c'est aussi comment vous le feriez manuellement).

Allez dans "Build Phase" > "Copy Bundler Resource", si cela n'a pas fonctionné, vous les ajouterez manuellement ici.

1_uuz0__3kx2vvguz37bhvya

Obtenir les noms de polices (reconnus par XCode)

Ouvrez d'abord vos journaux XCode, comme:

XXXX

Ensuite, vous pouvez ajouter le bloc suivant dans votre AppDelegate.mpour enregistrer les noms des polices et de la famille de polices.

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


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

  ...
}

Une fois que vous avez exécuté, vous devriez trouver vos polices si elles sont chargées correctement, ici nous avons trouvé les nôtres dans des journaux comme celui-ci:

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

Alors maintenant, nous savons qu'il a chargé la Verlagfamille et sont les polices à l'intérieur de cette famille

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

Ce sont maintenant les noms sensibles à la casse que nous pouvons utiliser dans notre famille de polices que nous pouvons utiliser dans notre application native react.

Vous avez maintenant défini la police par défaut.

Ensuite, pour définir une police par défaut pour ajouter le nom de votre famille de polices dans votre AppDelegate.mavec cette ligne

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

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

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

Terminé.

Garrettmac
la source
La meilleure approche, mais ne fonctionne pas, quelque chose lié à la mise à jour las de RN 0.57?
user2976753
2

Défini dans package.json

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

Et lien lien natif de réaction

puc12
la source
1

Cela fonctionne pour moi: ajouter une police personnalisée dans React Native

téléchargez vos polices et placez-les dans le dossier assets / fonts, ajoutez cette ligne dans package.json

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

puis ouvrez le terminal et exécutez cette commande: react-native link

Maintenant, vous êtes prêt à partir. Pour une étape plus détaillée. visitez le lien ci-dessus

Khushboo Tahir
la source