Come impostare la famiglia di caratteri predefinita in React Native?


98

Esiste un equivalente a questo CSS in React Native, in modo che l'app utilizzi lo stesso carattere ovunque?

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

Applicarlo manualmente su ogni nodo di testo sembra eccessivamente complicato.


1
Hai una risposta perfetta per questa domanda ??? Non voglio chiamare alcun styles.text o qualcosa del genere.
MD Ashik

Risposte:


70

Il modo consigliato è creare il proprio componente, come MyAppText. MyAppText sarebbe un componente semplice che rende un componente di testo usando il tuo stile universale e può passare attraverso altri oggetti di scena, ecc.

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


2
Grazie, è esattamente quello di cui avevo bisogno. Sembra che non abbia ancora afferrato abbastanza a fondo l'approccio dei componenti :)
Dagobert Renouf

2
Una cosa che non è molto chiara dai documenti è come passare attraverso le proprietà nel tuo componente e come rispettare gli stili sul tuo componente. Puoi farlo in questo modo: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar

1
@ NeilSarkar Un problema con questo esempio essenziale è che lo stile viene generato nel costruttore. Di conseguenza, se lo style prop cambia, vorresti che fosse nuovamente renderizzato, ma in questo caso non lo farà. Dovrebbe essere gestito al render()posto del costruttore. L'uso di ganci con useMemopotrebbe anche aiutare se l'efficienza è importante. In alternativa, se vuoi mantenerlo nel costruttore, è importante aggiungere una componentDidUpdatelogica che si aggiorni this.stylequando il componente si aggiorna a causa di un cambio di stile prop.
Fernando Rojo

buon punto, grazie! sembra che qualcuno abbia aggiunto anche una versione refactored all'essenza che combina gli stili nel metodo di rendering (di un componente puro, nel loro caso)
Neil Sarkar

58

Recentemente è stato creato un modulo nodo che risolve questo problema in modo da non dover creare un altro componente .

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

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

La documentazione afferma che nel componente di ordine più alto, importa la setCustomTextfunzione in questo modo.

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

Quindi, crea lo stile / oggetti di scena personalizzati che desideri per il Textcomponente nativo di reazione . Nel tuo caso, vorresti che fontFamily lavorasse su ogni Textcomponente.

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

Chiama la setCustomTextfunzione e passa i tuoi oggetti di scena / stili nella funzione.

setCustomText(customTextProps);

E poi tutti i Textcomponenti nativi di reazione avranno la tua fontFamily dichiarata insieme a qualsiasi altro oggetto / stile che fornisci.


Il metodo idiomatico per utilizzare la composizione dei componenti sembra una scelta migliore, anche se questo è un trucco interessante.
Daniel Little

Quando il componente Testo non supporta la modifica dei caratteri predefiniti immediatamente, questa soluzione diventa molto migliore. Preferirei di gran lunga aggiungere un controllo globale in un unico posto e utilizzare i componenti nativi piuttosto che creare un componente wrapper per ogni dettaglio fornito dalle vere app native.
mienaikoe

Ho esitato tra le 2 soluzioni precedenti, in realtà odio installare plug-in non ufficiali perché lo stesso react-native continua a cambiare, ma alla fine scelgo questa in quanto può davvero farmi risparmiare un'enorme quantità di tempo. Grazie!
Zhang Buzz

Quindi devo chiamare <Text style={styles.text}>?? Non è una soluzione perfetta come quella body {font-family: 'Open Sans';} ha una soluzione di aggiornamento ??
MD Ashik

1
No, non devi farlo Text style={styles.text}>. Hai solo bisogno di dichiarare i tuoi oggetti di scena personalizzati da qualche parte nella tua applicazione e verranno applicati a tutti i tuoi componenti di testo. È molto simile abody {font-family: ....}
Ajackster

31

Per React Native 0.56.0+ controlla se defaultProps è definito per primo:

Text.defaultProps = Text.defaultProps || {}

Poi aggiungi:

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

Aggiungi quanto sopra nel costruttore del file App.js (o qualsiasi componente radice che hai).

Per sovrascrivere lo stile puoi creare un oggetto stile e diffonderlo, quindi aggiungere il tuo stile aggiuntivo (ad es. { ...baseStyle, fontSize: 16 })


4
Forse defaultPropsnon esisteva quando tutte le altre risposte furono scritte, ma questo sembra essere il modo per farlo ora.
freeall

4
Sfortunatamente, non funzionerà se sovrascriviamo l' styleelica, ad esempio, per modificare gli stili di Textcomponenti particolari
Amerzilla

Vero ma puoi aggirare questo problema, creare lo stile comune come oggetto e quando vuoi un font personalizzato passa al componente un array che contiene quell'oggetto + yourNewStyleObject @Amerzilla
AJA

1
C'è un problema lì. Se poi qualcuno definisce il styleprop nel componente Text, il font predefinito verrà sostituito.
Broda Noel

2
è il 2019 e funziona perfettamente. ricorda solo che in Android non puoi usare "-" nei nomi dei file. definire i nomi dei file dei caratteri qualcosa come nome_font.ttf.
MRSafari

23

Puoi sovrascrivere il comportamento del testo aggiungendolo in qualsiasi componente utilizzando il testo:

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

Modifica: da React Native 0.56, Text.prototypenon funziona più. È necessario rimuovere .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
È un'ottima soluzione, ma devi cambiare: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] Altrimenti sovrascriverai lo stile personalizzato impostato nel componente
Iaconis Simone

1
Ha funzionato meglio. Text.prototype.render non funziona più, Text.render sì!
Kira

1
come evitare che le icone ereditino lo stesso?
mob

1
Sono d'accordo con @IaconisSimone Miglior approccio per impostare fontFamily e per essere sicuro di non sovrascrivere gli stili personalizzati
dczii

1
Questa è la strada da percorrere
Witalo Benicio

15

Inserisci

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

in package.json poi corrireact-native link


14

Con React-Native 0.56, il metodo di modifica di cui sopra Text.prototype.rendernon funziona più, quindi devi usare il tuo componente, che può essere fatto in una riga!

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 Ora sarà con ganci e useRef. reactjs.org/docs/hooks-reference.html#useref
Christopher Reid

11

Aggiungi questa funzione al tuo Appcomponente root e quindi eseguila dal tuo costruttore dopo aver aggiunto il tuo carattere usando queste istruzioni. 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;
            }
        };
    }
}

Questo è esattamente quello che stavo cercando, non volevo installare altro.
zevy_boy

Se il mio App.js è composto principalmente da const App = StackNavigator({...})e export default Appdove collocherei esattamente questo codice perché non penso di poter utilizzare un costruttore qui?
kojow7

Ho aggiunto la mia domanda qui: stackoverflow.com/questions/50081042/...
kojow7

Perché costruttore su componentDidMount?
Dror Bar

2

Super tardi per questo thread, ma qui va.

TLDR; Aggiungi il seguente blocco nel tuo fileAppDelegate.m

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

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

Procedura dettagliata dell'intero flusso.

Alcuni modi per farlo al di fuori dell'utilizzo di un plug-in come react-native-global-propscosì ti guiderò passo dopo passo.

Aggiunta di caratteri alle piattaforme.

Come aggiungere il carattere al progetto IOS

Per prima cosa creiamo una posizione per le nostre risorse. Facciamo la seguente directory alla nostra radice.

`` `

ios/
static/
       fonts/

`` `

Ora aggiungiamo un NPM "React Native" nel nostro package.json

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

Ora possiamo eseguire il "collegamento nativo di reazione" per aggiungere le nostre risorse alle nostre app native.

Verifica o esecuzione manuale.

Ciò dovrebbe aggiungere i nomi dei caratteri nei progetti .plist (per gli utenti di codice VS eseguiti code ios/*/Info.plistper confermare)

Supponiamo che Verlagsia il carattere che hai aggiunto, dovrebbe assomigliare a questo:

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

Ora che li hai mappati, ora assicuriamoci che siano effettivamente lì e vengano caricati (questo è anche il modo in cui lo faresti manualmente).

Vai a "Build Phase" > "Copy Bundler Resource", Se non ha funzionato, aggiungi manualmente sotto di loro qui.

1_uuz0__3kx2vvguz37bhvya

Ottieni nomi di font (riconosciuti da XCode)

Per prima cosa apri i tuoi registri XCode, come:

XXXX

Quindi puoi aggiungere il seguente blocco nel tuo AppDelegate.mper registrare i nomi dei caratteri e della famiglia di caratteri.

- (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 volta eseguito dovresti trovare i tuoi font se caricati correttamente, qui abbiamo trovato i nostri in log come questo:

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

Quindi ora sappiamo che ha caricato la Verlagfamiglia e sono i caratteri all'interno di quella famiglia

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

Questi sono ora i nomi sensibili al maiuscolo / minuscolo che possiamo usare nella nostra famiglia di caratteri che possiamo usare nella nostra app nativa di reazione.

Got -'em ora imposta il carattere predefinito.

Quindi, per impostare un carattere predefinito per aggiungere il nome della famiglia di caratteri nel tuo AppDelegate.mcon questa riga

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

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

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

Fatto.


L'approccio migliore, ma non funziona, qualcosa relativo al las update di RN 0.57?
user2976753

2

Impostato in package.json

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

E collega il link nativo di reazione


1

Per me funziona: aggiungi caratteri personalizzati in React Native

scarica i tuoi font e inseriscili nella cartella assets / fonts, aggiungi questa riga in package.json

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

quindi apri il terminale ed esegui questo comando: react-native link

Ora sei a posto. Per un passaggio più dettagliato. visitare il link sopra menzionato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.