facebook / react-native

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

[Text] font size is changing #2519

Closed aprilzero closed 8 years ago

aprilzero commented 9 years ago

Just upgraded to 11-rc and all <Text> font sizes are now being affected by accessibility settings.

Accessibility is great, but this ended up breaking many of our screens. It seems like it would be better to opt into that behavior. Our app wasn't designed for that extreme variability in font size, and I imagine many others weren't either.

We fixed the issue for now by adding allowFontScaling={false} to every text node, but obviously that is verbose and not optimal. It would be great to either have that be default, or a documented way to set it just once globally.

I believe the relevant commit is at https://github.com/facebook/react-native/commit/53fb5b6cee50f85bc6220231b2fd39fd94b587db

myusuf3 commented 9 years ago

:+1:

ide commented 9 years ago

FWIW I believe honoring the accessibility settings should be the default for the same reasons why a web browser lets you magnify text if you want to. Looking at my phone's apps, most of the text is for content more than presentation.

Easiest way to do it globally is maybe to override the default props (untested):

import { Text } from 'react-native';

let originalGetDefaultProps = Text.getDefaultProps;
Text.getDefaultProps = function() {
  return {
    ...originalGetDefaultProps(),
    allowFontScaling: false,
  };
};
yamill commented 9 years ago

Was wondering the same thing @aprilzero. Thanks for the allowFontScaling it resolved my issues.

aprilzero commented 9 years ago

I flipped through some of the top native apps on my phone—Facebook, Instagram, Snapchat, Uber, Calendar and Slack are fixed font sizes that do not follow the accessibility setting.

Others apps like Messenger, Twitter, Spotify, Mail scale the text based on the setting. Seems to be ones that are more text based and have a lot of reading.

IMHO it should be up to the app developer to decide which category their app falls into.

ide commented 9 years ago

Yeah that's fair. @a2 do you have thoughts on this?

a2 commented 9 years ago

It seems that this changed in 53fb5b6cee50f85bc6220231b2fd39fd94b587db. The commit message says that allowFontScaling should be false by default but the code and UIExplorer example say otherwise.

yamill commented 9 years ago

Ah so I guess this a bug. I can submit a quick PR.

yamill commented 9 years ago

I submitted a PR for this - https://github.com/facebook/react-native/pull/2530

myusuf3 commented 9 years ago

@yamill :+1:

vjeux commented 9 years ago

IMHO it should be up to the app developer to decide which category their app falls into.

In my experience, if you do not have accessibility features baked by default, then no one will really implement it properly. We've done a lot of work with React Native to get voice over working well by default: any element that is <Touchable*> will be accessible and the hint will be a concatenation of all the text inside (if any). We absolutely should have font scaling be the default, and if it doesn't work well with some screens of your app, then you can disable it.

Also, I just tried and Facebook does update some text to be bigger with accessibility settings: accessibility

ccheever commented 8 years ago

If this is the intended behavior can this issue be closed? Or is there more to do here? @aprilzero - maybe you could just make a NonScalingText component that wraps Text sets the prop such that the text doesn't scale?

brentvatne commented 8 years ago

@ccheever - I think you're right that this can be closed now, this option won't be changed -- defining your own Text component to reduce boilerplate seems like a solution where necessary.

GantMan commented 8 years ago

I know this issue is closed, but I think we conflated two questions, and left the more important one discarded.

YES it should default to true, and because it's an option, it should be a simple global (not just per instance) for the developer to disable app-wide. @ccheever and @brentvatne please consider that as we utilize 3rd party node modules, we don't always have access to the underlying textviews to restructure them to a nonscaling text.

brentvatne commented 8 years ago

Good point @GantMan - can you create an issue on ProductPains for this?

GantMan commented 8 years ago

consider it done!

12d commented 8 years ago

I found a solution,Text.defaultProps.allowFontScaling=false, it works, it is global

uc-hus commented 7 years ago

12d, Please give me example for Text.defaultProps.allowFontScaling=false

GantMan commented 7 years ago

@uc-hus - you could throw this in your index.ios.js just import text and modify it's defaultProps. Done! All subsequent uses of Text will have font scaling set to false. Super easy 👍

uc-hus commented 7 years ago

Gant, Please provide a example!

GantMan commented 7 years ago

@uc-hus - I made a PR to Ignite to expose this option in AppSettings.js.
I hope this example helps: https://github.com/infinitered/ignite/pull/389

uc-hus commented 7 years ago

Its not working. Please do something if possible.

Thanks & Regards Mohammed HUSAIN Senior Apps Developer, uCertify +91 9919475253

On Sun, Sep 25, 2016 at 11:36 PM, Gant Laborde notifications@github.com wrote:

@uc-hus https://github.com/uc-hus - I made a PR to Ignite to expose this option in AppSettings.js.

I hope this example helps: infinitered/ignite#389 https://github.com/infinitered/ignite/pull/389

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/facebook/react-native/issues/2519#issuecomment-249436174, or mute the thread https://github.com/notifications/unsubscribe-auth/ALoZ1DR6x9W15pT7TTytV0xfnoPPQD0Iks5qtrgngaJpZM4F2Ixk .

GantMan commented 7 years ago

Gonna need more info than that. How about we move this convo off to the reactiflux dischord channel. I am Gantman there, as well https://discordapp.com/channels/102860784329052160/102861040538120192

ytqiu commented 7 years ago

I'm using 0.33.0 with Android, set allowFontScaling=false is not working. At the end, i use ${targetDP} * PixelRatio.get() / PixelRatio.getFontScale() temporarily to hack it.

SudoPlz commented 7 years ago

I've found out by experience that if you correctly design your app to use points instead of pixel font sizes, you don't need to disable allowFontScaling and you don't need ANY fancy code to choose the right font size for your elements.

I just tell our designer to design for an iPhone 5, and use Points in his mockups, and all magically just works.

devrockzz commented 7 years ago

Hi everyone i am going throught this issue " Text.defaultProps.allowFontScaling=false" solved my problem in IOS but it did not solved this issue in android . So is there any why to turn allowFontScaling = false in android ?

dincozdemir commented 7 years ago

I've put "Text.defaultProps.allowFontScaling=false" in the constructor of index.android.js and it worked.


import { Text } from 'react-native';
...
constructor() {
  super();
  Text.defaultProps.allowFontScaling=false;
}
TimonSotiropoulos commented 7 years ago

I know this is a closed issue, but I am still having an issue with font scaling even after following the above tricks to disable fontScaling on Text Components.

It seems the above trick doesn't stop the Text from scaling when a user sets their Display Zoom settings to "Zoomed" instead of "Standard". Has anyone found a solution to this issue?

The Display Zoom settings can be found on iPhone 6 and up under Settings > Display & Brightness > Display Zoom.

Thanks in Advance!

vmacavero commented 7 years ago

Hi all, hi @TimonSotiropoulos , did you manage to find a workaround ? I have the same problem.

Victor

TimonSotiropoulos commented 7 years ago

@vmacavero No I haven't found a solution. Just had to redesign some of my screens so they worked in both standard and zoomed modes.

administerspice commented 7 years ago

These two solutions work globally for iOS but not for Android. Any solutions for setting allowFontScaling=false globally on Android? Solution 1: Set in root constructor constructor() { super(); Text.defaultProps.allowFontScaling = false; } Solution 2: Set in index file let originalGetDefaultProps = Text.defaultProps; Text.defaultProps = function() { return { ...originalGetDefaultProps, allowFontScaling: false, }; };

mnsrv commented 6 years ago

This works on Android too Text.defaultProps.allowFontScaling = false

For TextInput I added prop allowFontScaling={false} and it worked too.

e.g. <TextInput allowFontScaling={false} />

idws commented 6 years ago

I have a problem for this case. I've add the Text.defaultProps.allowFontScaling = false in the index.android.js it's works fine except for the case where there's a <Text></Text> inside a <Text></Text> like this, `...

This is a sentence with one word in bold

...` and it's only happen in the android.

is there any solution for this? Thanks in advance

yaronlevi commented 6 years ago

+1 for nested <Text><Text>this text is not affected by setting allowFontScaling to false</Text></Text>

weijiederrick91 commented 6 years ago

hi any one face any issue with android screen zoom and how to disable the screen zoom ?

MarcelBlockchain commented 6 years ago

Text.defaultProps.allowFontScaling = false in constructor in App.js (using Expo) works great for me! Except for placeholder in TextInput, probably because it's a nested Text in Text. Well, minor problem^^

anshul-kai commented 6 years ago

This no longer works on react-native 0.56.0. Text.defaultProps is undefined.

DevPravin commented 6 years ago

Does dynamic type is supported by latest React-Native version?

Reading through the post understand that, it doesn't want to support the dynamic type then set allowFontScaling = false since default value of allowFontScaling is true. But still dynamic type (font scaling) is not working when allowFontScaling=true set.

oded-gong-io commented 6 years ago

@a-koka can you please provide a reference to the change in 0.56.0?

anshul-kai commented 6 years ago

I have not had the chance to investigate the source code @oded-gong-io as I'm still fighting with all the breaking changes in my app since the upgrade, nothing major, I still love react-native and the forces behind it :)

All I can say for certain is that I was using Text.defaultProps.allowFontScaling to disable font scaling and this is now breaking. I also verified on a brand new project and Text.defaultProps is indeed coming back as undefined which wasn't the case in 0.55.4.

patrickkempff commented 6 years ago

@a-koka I think this is because the Text component is wrapped to inject the forwardedRef prop, see https://github.com/facebook/react-native/blob/e1cca18d0081f803013fe60d38d89f7f44dafca0/Libraries/Text/Text.js#L264-L269

I am not entirely sure if overwriting the default props of build-in components is currently supported. But to fix your issue you can wrap RN's text component with your own, by doing something alone the lines of:

// custom Text.js
import React, { Component } from 'react';
import { Text as BaseText } from 'react-native';

export default class Text extends Component {
   render () {
      return <BaseText allowFontScaling={false} {...this.props} />
   }
}

// or if you prefer a functional component:

const Text = ({ allowFontScaling = false, ...props }) => {
   return <BaseText allowFontScaling={allowFontScaling} {...props} />
}

export default Text;

Please beware of typo's as i am typing this on mobile

anshul-kai commented 6 years ago

Thanks for pointing me to this @patrickkempff. You're absolutely right on both fronts. I do realize that I can just wrap my customizations in a new component but that does require a lot of changes on my end as I have a really large app. Hoping there is some way to override the defaultProps in the near future. If not, writing a custom component does suffice and isn't a terrible solution.

levibuzolic commented 6 years ago

If you still want to change this globally you can use:

if (Text.defaultProps == null) Text.defaultProps = {};
Text.defaultProps.allowFontScaling = false;

However ideally you should be allowing font scaling and instead spend the time/effort to fix your layout issues to handle different font scales.

anshul-kai commented 6 years ago

Thanks for the hack @levibuzolic. I agree that I should consider font scaling for all my layouts but with so much to do, such hacks are necessary. Glad this was an easy fix. Appreciate the help!