Wie lege ich die Standardschriftfamilie in React Native fest?


95

Gibt es ein Äquivalent zu diesem CSS in React Native, sodass die App überall dieselbe Schriftart verwendet?

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

Das manuelle Anwenden auf jeden Textknoten scheint zu kompliziert.


1
Haben Sie eine perfekte Antwort auf diese Frage? Ich möchte keinen styles.text oder ähnliches aufrufen.
MD Ashik

Antworten:


67

Die empfohlene Methode besteht darin, eine eigene Komponente wie MyAppText zu erstellen. MyAppText ist eine einfache Komponente, die eine Textkomponente mit Ihrem universellen Stil rendert und andere Requisiten usw. passieren kann.

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


2
Danke, genau das habe ich gebraucht. Scheint, als hätte ich den Komponentenansatz noch nicht tief genug verstanden :)
Dagobert Renouf

2
Eine Sache, die aus den Dokumenten nicht besonders klar hervorgeht, ist, wie Sie Eigenschaften in Ihrer Komponente durchlaufen und Stile in Ihrer Komponente respektieren. Sie können dies folgendermaßen tun: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar

1
@NeilSarkar Ein Problem mit diesem Hauptbeispiel ist, dass der Stil im Konstruktor generiert wird. Wenn sich die Stil-Requisite ändert, möchten Sie, dass sie erneut gerendert wird. In diesem Fall wird dies jedoch nicht der Fall sein. Es sollte render()anstelle des Konstruktors behandelt werden. Die Verwendung von Haken mit useMemokann auch hilfreich sein, wenn Effizienz wichtig ist. Wenn Sie es alternativ im Konstruktor behalten möchten, ist es wichtig, eine componentDidUpdateLogik hinzuzufügen , die aktualisiert wird, this.stylewenn die Komponente aufgrund einer Änderung der Stilstütze aktualisiert wird.
Fernando Rojo

Guter Punkt, danke! Es sieht so aus, als hätte jemand dem Kern eine überarbeitete Version hinzugefügt, die die Stile in der Rendermethode (in ihrem Fall einer reinen Komponente) kombiniert
Neil Sarkar,

58

Es gab vor kurzem ein Knotenmodul, das diese löst dieses Problem gemacht wurde , so dass Sie nicht haben , um eine weitere Komponente zu erstellen .

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

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

In der Dokumentation heißt es, dass Sie die setCustomTextFunktion in Ihrer Komponente höchster Ordnung wie folgt importieren .

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

Erstellen Sie dann das gewünschte benutzerdefinierte Styling / Requisiten für die reaktionsnative TextKomponente. In Ihrem Fall möchten Sie, dass fontFamily an jeder TextKomponente arbeitet.

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

Rufen Sie die setCustomTextFunktion auf und übergeben Sie Ihre Requisiten / Stile an die Funktion.

setCustomText(customTextProps);

Und dann haben alle reaktionsnativenText Komponenten Ihre deklarierte fontFamily zusammen mit allen anderen Requisiten / Stilen, die Sie bereitstellen.


Die idiomatische Methode zur Verwendung der Komponentenzusammensetzung scheint eine bessere Wahl zu sein, obwohl dies ein cooler Hack ist.
Daniel Little

Wenn die Textkomponente das sofortige Ändern von Standardschriftarten nicht unterstützt, wird diese Lösung viel besser. Ich würde viel lieber ein globales Steuerelement an einem Ort hinzufügen und die nativen Komponenten verwenden, als eine Wrapper-Komponente für jedes Detail zu erstellen, das echte native Apps bieten.
Mienaikoe

Ich habe zwischen den beiden oben genannten Lösungen gezögert. Eigentlich hasse ich es, inoffizielle Plugins zu installieren, da sich die Reaktion selbst weiterhin ändert, aber schließlich wähle ich diese, da sie mir wirklich viel Zeit sparen kann. Vielen Dank!
Zhang Buzz

SO muss ich anrufen <Text style={styles.text}>?? Es ist keine perfekte Lösung wie diese body {font-family: 'Open Sans';} haben eine Update-Lösung?
MD Ashik

1
Nein, das musst du nicht tun Text style={styles.text}>. Sie müssen Ihre benutzerdefinierten Requisiten nur irgendwo in Ihrer Anwendung deklarieren und sie werden auf alle Ihre Textkomponenten angewendet. Es ist sehr ähnlich zubody {font-family: ....}
Ajackster

30

Überprüfen Sie für React Native 0.56.0+ zuerst, ob defaultProps definiert ist:

Text.defaultProps = Text.defaultProps || {}

Dann füge hinzu:

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

Fügen Sie das Obige im Konstruktor der Datei App.js (oder einer beliebigen Stammkomponente) hinzu.

Um den Stil zu überschreiben , können Sie ein Style - Objekt erstellen und verbreiten es Ihre zusätzlichen Stil fügen Sie dann (zB { ...baseStyle, fontSize: 16 })


4
Vielleicht gab es das defaultPropsnicht, als alle anderen Antworten geschrieben wurden, aber dies scheint jetzt der richtige Weg zu sein.
freeall

4
Leider wird es nicht funktionieren, wenn wir beispielsweise die styleStütze überschreiben , um die Stile bestimmter TextKomponenten zu optimieren
Amerzilla,

Richtig, aber Sie können dies umgehen, den allgemeinen Stil als Objekt erstellen und, wann immer Sie eine benutzerdefinierte Schriftart möchten, einfach ein Array an die Komponente übergeben, das dieses Objekt enthält + yourNewStyleObject @Amerzilla
AJA

1
Da gibt es ein Problem. Wenn dann jemand die styleRequisite in der Textkomponente definiert , wird die Standardschrift ersetzt.
Broda Noel

2
Es ist 2019 und es funktioniert perfekt. Denken Sie daran, in Android können Sie nicht "-" in Dateinamen verwenden. Definieren Sie Ihre Schriftdateinamen wie font_name.ttf.
MRSafari

22

Sie können das Textverhalten überschreiben, indem Sie es mit Text in eine beliebige Komponente einfügen:

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

Bearbeiten: Text.prototypefunktioniert seit React Native 0.56 nicht mehr. Sie müssen Folgendes entfernen .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
Das ist eine großartige Lösung, aber Sie müssen Folgendes ändern: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] Andernfalls überschreiben Sie den in der Komponente festgelegten benutzerdefinierten Stil
Iaconis Simone

1
Hat am besten funktioniert. Text.prototype.render funktioniert nicht mehr, Text.render!
Kira

1
Wie vermeide ich, dass Symbole dasselbe erben?
Mob

1
Ich bin mit @IaconisSimone einverstanden. Bester Ansatz, um fontFamily festzulegen und um sicherzustellen, dass benutzerdefinierte Stile nicht überschrieben werden
dczii

1
Dies ist der
richtige

15

Hinzufügen

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

in package.json dann laufenreact-native link


14

Mit React-Native 0.56 Text.prototype.renderfunktioniert die oben beschriebene Änderungsmethode nicht mehr. Sie müssen also Ihre eigene Komponente verwenden, was in einer Zeile erfolgen kann!

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 Es wird jetzt mit Haken und useRef. reactjs.org/docs/hooks-reference.html#useref
Christopher Reid

11

Fügen Sie diese Funktion Ihrer Stammkomponente hinzu Appund führen Sie sie dann von Ihrem Konstruktor aus, nachdem Sie Ihre Schriftart mithilfe dieser Anweisungen hinzugefügt haben. 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;
            }
        };
    }
}

Genau das habe ich gesucht, wollte nichts mehr installieren.
zevy_boy

Wenn meine App.js hauptsächlich aus const App = StackNavigator({...})und export default Appwo genau würde ich diesen Code platzieren, da ich nicht glaube, dass ich hier einen Konstruktor verwenden kann?
Kojow7

Ich habe meine eigene Frage hier hinzugefügt: stackoverflow.com/questions/50081042/…
kojow7

Warum Konstruktor über componentDidMount?
Dror Bar

2

Super spät zu diesem Thread aber hier geht.

TLDR; Fügen Sie den folgenden Block in IhreAppDelegate.m

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

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

Walkthrough des gesamten Flusses.

Ein paar Möglichkeiten, wie Sie dies außerhalb der Verwendung eines Plugins wie tun können react-native-global-props Sie Schritt für Schritt durch.

Hinzufügen von Schriftarten zu Plattformen.

So fügen Sie die Schriftart zum IOS-Projekt hinzu

Lassen Sie uns zunächst einen Standort für unser Vermögen erstellen. Lassen Sie uns das folgende Verzeichnis in unserem Stammverzeichnis erstellen.

`` `

ios/
static/
       fonts/

`` `

Fügen wir nun ein "React Native" -NPM in unser package.json ein

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

Jetzt können wir "React-Native Link" ausführen, um unsere Assets zu unseren nativen Apps hinzuzufügen.

Überprüfen oder manuell ausführen.

Das sollte Ihre Schriftnamen in die Projekte .plist einfügen (für VS-Code-Benutzer ausführencode ios/*/Info.plist zur Bestätigung )

Nehmen wir hier an, es Verlaghandelt sich um die Schriftart, die Sie hinzugefügt haben. Sie sollte ungefähr so ​​aussehen:

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

Nachdem Sie sie zugeordnet haben, stellen wir sicher, dass sie tatsächlich vorhanden sind und geladen werden (so würden Sie es auch manuell machen).

Gehen Sie zu "Build Phase" > "Copy Bundler Resource", Wenn es nicht funktioniert hat, fügen Sie hier manuell ein.

1_uuz0__3kx2vvguz37bhvya

Schriftarten abrufen (von XCode erkannt)

Öffnen Sie zuerst Ihre XCode-Protokolle wie folgt:

XXXX

Anschließend können Sie den folgenden Block hinzufügen AppDelegate.m, um die Namen der Schriftarten und der Schriftfamilie zu protokollieren.

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


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

  ...
}

Sobald Sie ausgeführt haben, sollten Sie Ihre Schriftarten finden, wenn sie korrekt geladen wurden. Hier haben wir unsere in folgenden Protokollen gefunden:

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

Jetzt wissen wir also, dass es die VerlagFamilie geladen hat und die Schriftarten innerhalb dieser Familie sind

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

Dies sind jetzt die Namen, bei denen zwischen Groß- und Kleinschreibung unterschieden wird und die wir in unserer Schriftfamilie verwenden können, die wir in unserer reaktionsfähigen nativen App verwenden können.

Got -'em setzt jetzt die Standardschriftart.

Legen Sie dann eine Standardschrift fest, um Ihren Schriftfamiliennamen AppDelegate.mmit dieser Zeile in Ihre einzufügen

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

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

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

Getan.


Der beste Ansatz, aber funktioniert nicht, irgendetwas im Zusammenhang mit dem Las-Update von RN 0.57?
user2976753

2

In package.json einstellen

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

Und Link React-Native Link


1

Das ist für mich in Ordnung: Benutzerdefinierte Schriftart in React Native hinzufügen

Laden Sie Ihre Schriftarten herunter und legen Sie sie im Ordner Assets / Fonts ab. Fügen Sie diese Zeile in package.json hinzu

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

Öffnen Sie dann das Terminal und führen Sie diesen Befehl aus: react-native link

Jetzt können Sie loslegen. Für einen detaillierteren Schritt. Besuchen Sie den oben genannten Link

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.