Jak ustawić domyślną rodzinę czcionek w React Native?

100

Czy istnieje odpowiednik tego CSS w React Native, aby aplikacja wszędzie używała tej samej czcionki?

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

Ręczne stosowanie go w każdym węźle tekstowym wydaje się zbyt skomplikowane.

Dagobert Renouf
źródło
1
Masz jakąś idealną odpowiedź na to pytanie ??? Nie chcę nazywać żadnych styles.text ani niczego podobnego.
MD Ashik,

Odpowiedzi:

70

Zalecanym sposobem jest utworzenie własnego komponentu, takiego jak MyAppText. MyAppText byłby prostym komponentem, który renderuje komponent Text przy użyciu Twojego uniwersalnego stylu i może przechodzić przez inne rekwizyty itp.

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

David E. Chen
źródło
2
Dzięki, właśnie tego potrzebowałem. Wygląda na to, że nie pojąłem jeszcze wystarczająco głęboko podejścia komponentu :)
Dagobert Renouf
2
Jedna rzecz, która nie jest bardzo jasna w dokumentacji, to jak przekazywać właściwości w komponencie i szanować style w komponencie. Możesz to zrobić w ten sposób: gist.github.com/neilsarkar/c9b5fc7e67bbbe4c407eec17deb7311e
Neil Sarkar
1
@NeilSarkar Jednym z problemów z tym głównym przykładem jest to, że styl jest generowany w konstruktorze. W rezultacie, jeśli zmieni się rekwizyt stylu, chciałbyś go ponownie wyrenderować, ale w tym przypadku tak się nie stanie. Powinien być obsługiwany w render()zamiast konstruktora. Używanie haków z useMemomoże również pomóc, jeśli ważna jest wydajność. Alternatywnie, jeśli chcesz zachować go w konstruktorze, ważne jest, aby dodać componentDidUpdatelogikę, która aktualizuje się, this.stylegdy składnik aktualizuje się z powodu zmiany właściwości stylu.
Fernando Rojo
słuszna uwaga, dzięki! wygląda na to, że ktoś dodał refaktoryzowaną wersję do sedna, która łączy style w metodzie renderowania (w ich przypadku czystego komponentu)
Neil Sarkar
59

Niedawno powstał moduł węzła, który rozwiązuje ten problem, więc nie trzeba tworzyć kolejnego komponentu .

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

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

Dokumentacja stwierdza, że ​​w komponencie najwyższego rzędu zaimportuj setCustomTextfunkcję w ten sposób.

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

Następnie utwórz własne style / rekwizyty, które chcesz dla Textkomponentu reagującego . W Twoim przypadku chcesz, aby fontFamily działał na każdym Textkomponencie.

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

Wywołaj setCustomTextfunkcję i przekaż swoje właściwości / style do funkcji.

setCustomText(customTextProps);

A następnie wszystkie Textkomponenty typu act -native będą miały zadeklarowaną przez Ciebie czcionkę fontFamily wraz z innymi podanymi właściwościami / stylami.

Ajackster
źródło
Idiomatyczny sposób wykorzystania kompozycji komponentów wydaje się lepszym wyborem, chociaż to fajny hack.
Daniel Little
Gdy składnik Text nie obsługuje zmiany domyślnych czcionek po wyjęciu z pudełka, to rozwiązanie staje się znacznie lepsze. O wiele wolałbym dodać globalną kontrolę w jednym miejscu i używać natywnych komponentów niż tworzyć komponent opakowujący dla każdego szczegółu, który zapewniają prawdziwe natywne aplikacje.
mienaikoe
Wahałem się między powyższymi 2 rozwiązaniami, właściwie nienawidzę instalować nieoficjalnych wtyczek, ponieważ samo reakcja-natywna wciąż się zmienia, ale w końcu wybieram to, ponieważ może naprawdę zaoszczędzić mi ogromną ilość czasu. Dzięki!
Zhang Buzz
Więc muszę zadzwonić <Text style={styles.text}>? To nie jest idealne rozwiązanie, takie jak to, czy body {font-family: 'Open Sans';} masz jakieś rozwiązanie do aktualizacji?
MD Ashik,
1
Nie, nie musisz tego robić Text style={styles.text}>. Musisz tylko zadeklarować swoje własne właściwości gdzieś w aplikacji, a zostaną one zastosowane do wszystkich komponentów Text. Jest bardzo podobny dobody {font-family: ....}
Ajackster,
32

Dla React Native 0.56.0+ sprawdź, czy defaultProps jest zdefiniowane jako pierwsze:

Text.defaultProps = Text.defaultProps || {}

Następnie dodaj:

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

Dodaj powyższe do konstruktora pliku App.js (lub dowolnego posiadanego komponentu głównego).

Aby nadpisać styl, możesz utworzyć obiekt stylu i rozszerzyć go, a następnie dodać swój dodatkowy styl (np. { ...baseStyle, fontSize: 16 })

AJA
źródło
4
Może defaultPropsnie istniało, gdy wszystkie inne odpowiedzi zostały napisane, ale wydaje się, że teraz jest to sposób na zrobienie tego.
cały
4
Niestety, to nie będzie działać, jeśli zastępują stylerekwizyt, powiedzmy, aby dostosować style poszczególnych Textkomponentów
Amerzilla
To prawda, ale możesz to obejść, stworzyć wspólny styl jako obiekt, a kiedy tylko zechcesz jakąś niestandardową czcionkę, po prostu przekaż do komponentu tablicę zawierającą ten obiekt + yourNewStyleObject @Amerzilla
AJA
1
Tu jest problem. Jeśli ktoś następnie zdefiniuje właściwość stylew komponencie Tekst, domyślna czcionka zostanie zastąpiona.
Broda Noel
3
jest rok 2019 i działa idealnie. pamiętaj tylko, że w Androidzie nie możesz używać „-” w nazwach plików. zdefiniuj nazwy plików czcionek, takie jak nazwa_czcionki.ttf.
MRSafari
24

Możesz nadpisać zachowanie Tekst, dodając to w dowolnym komponencie za pomocą Tekst:

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

Edycja: od React Native 0.56 Text.prototypejuż nie działa. Musisz usunąć .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
źródło
4
To świetne rozwiązanie, ale musisz zmienić: [origin.props.style, {color: 'red', fontFamily: 'Arial'}] -> [{color: 'red', fontFamily: 'Arial'}, origin. props.style] W przeciwnym razie zastąpisz niestandardowy styl ustawiony w komponencie
Iaconis Simone
1
Działało najlepiej. Text.prototype.render już nie działa, Text.render już nie działa!
Kira,
1
jak uniknąć dziedziczenia tego samego przez ikony?
Venkat
1
Zgadzam się z @IaconisSimone Najlepsze podejście do ustawiania fontFamily i nie zastępowania niestandardowych stylów
dczii
1
To jest droga
Witalo Benicio
14

W przypadku React-Native 0.56 powyższa metoda zmiany Text.prototype.renderjuż nie działa, więc musisz użyć własnego komponentu, co można zrobić w jednej linii!

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>
...
anni
źródło
@FancyJohn Będzie teraz z hakami i useRef. actjs.org/docs/hooks-reference.html#useref
Christopher Reid,
11

Dodaj tę funkcję do Appkomponentu głównego , a następnie uruchom ją z konstruktora po dodaniu czcionki zgodnie z tymi instrukcjami. 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;
            }
        };
    }
}
Obrabować
źródło
To jest dokładnie to, czego szukałem, nie chciałem niczego instalować.
zevy_boy
Jeśli mój plik App.js składa się głównie z const App = StackNavigator({...})i export default Appgdzie dokładnie powinienem umieścić ten kod, ponieważ nie sądzę, żebym mógł tu użyć konstruktora?
kojow7
Dodałem tutaj własne pytanie: stackoverflow.com/questions/50081042/…
kojow7
Dlaczego konstruktor zamiast componentDidMount?
Dror Bar
2

Bardzo późno do tego wątku, ale proszę bardzo.

TLDR; Dodaj następujący blok do swojegoAppDelegate.m

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

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

Przejście całego przepływu.

Na kilka sposobów możesz to zrobić poza używaniem wtyczki, takiej jak ta react-native-global-props, którą przeprowadzę Cię krok po kroku.

Dodawanie czcionek do platform.

Jak dodać czcionkę do projektu IOS

Najpierw stwórzmy lokalizację dla naszych aktywów. Zróbmy następujący katalog w naszym katalogu głównym.

`` ''

ios/
static/
       fonts/

`` ''

Teraz dodajmy NPM „React Native” do naszego package.json

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

Teraz możemy uruchomić „łącze do natywnego reagowania”, aby dodać nasze zasoby do naszych natywnych aplikacji.

Weryfikacja lub wykonanie ręczne.

To powinno dodać nazwy czcionek do projektów .plist (dla użytkowników kodu VS uruchomionych w code ios/*/Info.plistcelu potwierdzenia)

Tutaj załóżmy, że Verlagdodana czcionka powinna wyglądać mniej więcej tak:

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

Teraz, gdy je zmapowałeś, upewnijmy się, że faktycznie tam są i są ładowane (tak też zrobiłbyś to ręcznie).

Idź do "Build Phase" > "Copy Bundler Resource", jeśli to nie zadziałało, ręcznie dodasz pod nimi tutaj.

1_uuz0__3kx2vvguz37bhvya

Pobierz nazwy czcionek (rozpoznawane przez XCode)

Najpierw otwórz swoje dzienniki XCode, takie jak:

XXXX

Następnie możesz dodać następujący blok do swojego, AppDelegate.maby rejestrować nazwy czcionek i rodziny czcionek.

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


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

  ...
}

Po uruchomieniu powinieneś znaleźć swoje czcionki, jeśli zostały poprawnie załadowane, tutaj znaleźliśmy nasze w dziennikach takich jak ten:

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

Więc teraz wiemy, że załadował Verlagrodzinę i czy są czcionkami wewnątrz tej rodziny

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

Są to teraz nazwy z uwzględnieniem wielkości liter, których możemy używać w naszej rodzinie czcionek, których możemy używać w naszej natywnej aplikacji React.

Got -'em teraz ustaw domyślną czcionkę.

Następnie, aby ustawić domyślną czcionkę, aby dodać nazwę rodziny czcionek w AppDelegate.mtym wierszu

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

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

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

Gotowe.

garrettmac
źródło
Najlepsze podejście, ale nie działa, coś związanego z ostatnią aktualizacją RN 0.57?
user2976753
1

U mnie to działa: dodaj niestandardową czcionkę w React Native

pobierz swoje czcionki i umieść je w folderze asset / fonts, dodaj ten wiersz do pliku package.json

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

następnie otwórz terminal i uruchom polecenie: Reaguj-natywny link

Teraz możesz już iść. Aby uzyskać bardziej szczegółowy krok. odwiedź powyższy link

Khushboo Tahir
źródło
1

Dodaj

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

w package.json to biegnijreact-native link

Sanjib Suna
źródło
1

Ustaw w package.json

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

I link reaguj-natywny link

amin mohammadi
źródło