facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.37k stars 24.25k forks source link

Custom fonts not working on React-Native 0.65.1 #32345

Closed 31Karishma closed 2 years ago

31Karishma commented 2 years ago

Description

I want to use some custom font family in my app. I integrate custom font files properly but still it's not working. I'm not getting any error.

React Native version: 0.65.1

I integrate custom font by below 3 steps:

  1. First I creating assets folder on root project. Inside assets folder I create another folder fonts (assets/fonts). Inside fonts folder I added all my custom font .ttf files.

  2. After I creating react-native.config.js file on root project with the following code: module.exports = { project: { ios: {}, android: {}, }, assets: ['./assets/fonts'], };

  3. At last I run npx react-native link in terminal.

info Linking assets to ios project info Linking assets to android project success Assets have been successfully linked to your project

Expected Results

Font style will change.

Thank you.

witalobenicio commented 2 years ago

For me it's the same problem. It worked well on react-native 0.62.x but in 0.65.1 not working. It changes the font in tabbar, navBar, but not in react-native views.

witalobenicio commented 2 years ago

@31Karishma do you know if 0.65.0 works?

31Karishma commented 2 years ago

@31Karishma do you know if 0.65.0 works?

@witalobenicio Yes It's working in latest RN version.

Actually, it was my mistake, I wrote wrong spelling of font family name. That's why it's not working well.

Thank you :)

witalobenicio commented 2 years ago

@31Karishma Ive updated to latest version but isn't working. Previously I had 0.62.3 version (working fine) and upgraded to 0.65.1 and after that to 0.66.1, and it didn't worked in both. Any clue?

witalobenicio commented 2 years ago

@31Karishma I've fixed. The problem is that I was doing a font fix to apply the fontFamily to all Text instances. The problem is that react-native changed how Text is built. Now it has some container wrapping the Text that now is a children of the root component.

For anyone wondering how to do this:

const oldRender = Text.render;
Text.render = function(...args) {
    const origin = oldRender.call(this, ...args);
    const textOrigin = origin.props.children;
    const style = styleGenerator(textOrigin);
    const newText = React.cloneElement(textOrigin, {
      ...textOrigin.props,
      style,
    });
    return React.cloneElement(origin, {
      ...origin.props,
      children: newText,
    });
  };
KingAmo commented 2 years ago

@31Karishma I've fixed. The problem is that I was doing a font fix to apply the fontFamily to all Text instances. The problem is that react-native changed how Text is built. Now it has some container wrapping the Text that now is a children of the root component.

For anyone wondering how to do this:

const oldRender = Text.render;
Text.render = function(...args) {
    const origin = oldRender.call(this, ...args);
    const textOrigin = origin.props.children;
    const style = styleGenerator(textOrigin);
    const newText = React.cloneElement(textOrigin, {
      ...textOrigin.props,
      style,
    });
    return React.cloneElement(origin, {
      ...origin.props,
      children: newText,
    });
  };

Excuse me, what does styleGenerator do ?

newyangkun commented 2 years ago

@31Karishma I've fixed. The problem is that I was doing a font fix to apply the fontFamily to all Text instances. The problem is that react-native changed how Text is built. Now it has some container wrapping the Text that now is a children of the root component. For anyone wondering how to do this:

const oldRender = Text.render;
Text.render = function(...args) {
    const origin = oldRender.call(this, ...args);
    const textOrigin = origin.props.children;
    const style = styleGenerator(textOrigin);
    const newText = React.cloneElement(textOrigin, {
      ...textOrigin.props,
      style,
    });
    return React.cloneElement(origin, {
      ...origin.props,
      children: newText,
    });
  };

Excuse me, what does styleGenerator do ?

thanks @31Karishma gave me ideas. I realized it:

import React from 'react';
import { StyleSheet, Text, Platform } from 'react-native';

const styles = StyleSheet.create({
  defaultFontFamily: {
    fontFamily: '',
  },
});

if (Platform.OS !== 'ios') {
  const oldRender = Text.render;
  Text.render = function (...args) {
    const origin = oldRender.call(this, ...args);
    const textOrigin = origin.props.children;
    if (textOrigin.props) {
      const newText = React.cloneElement(textOrigin, {
        style: [styles.defaultFontFamily, textOrigin.props.style],
        allowFontScaling: false,
      });
      return React.cloneElement(origin, {
        style: [styles.defaultFontFamily, origin.props.style],
        children: newText,
      });
    }
    return React.cloneElement(origin, {
      style: [styles.defaultFontFamily, origin.props.style],
      allowFontScaling: false,
    });
  };
}
witalobenicio commented 2 years ago

Excuse me, what does styleGenerator do ?

@KingAmo it creates a default style (basically applies correct fontFamily based on fontWeight) for all Text component used in my application. I had to do this because our application was already big and to replace every Text component to a custom one would take a huge amount of time.

witalobenicio commented 2 years ago

@newyangkun In fact, I gave you ideas. hahaha 😅