如何在React Native的IOS和Android应用程序中禁用字体缩放?

66

设备字体大小的放大有时会破坏样式。


1
这是一个糟糕的选择,因为它会伤害那些视力不佳、手抖或其他运动障碍的用户,使他们难以与小触摸目标进行交互。更好的解决方案是修复你的样式,使字体更改不会破坏它。(例如,不要使用固定高度或宽度。) - Aaron Brager
4
@AaronBrager,并非总是如此,在小型设备上,几乎不可能“修复”您的样式以使文本适合同一行上。因此,除非您的屏幕上没有太多文本要查看,否则您可以更加考虑周到。因此,这完全是可选的,不是强制性的。无论适合您的需求,您都可以这样做。 - A-J-A
2
它不必在同一行上。将字体大小调整到最大的用户很高兴看到尴尬的文本换行。 - Aaron Brager
2
如果项目所有者不希望他们的应用程序出现这种情况,他们可以使用这个。否则,他们可以完全忽略它,并保持字体自动调整大小。再次强调,这是完全可选的。@AaronBrager - A-J-A
9个回答

119

禁用字体缩放可能会损害您的应用程序的可访问性。如果您想限制使用 React Native 0.58.0 及以上版本的应用程序的缩放,请在特定Text组件上使用maxFontSizeMultiplier属性

但是,如果您确实希望在整个应用程序中禁用字体缩放,则可以通过在TextdefaultProps中全局设置allowFontScaling属性来实现。

您应该将这些行放置在根入口点(通常为index.js)中,并在AppRegistry.registerComponent之前执行。

适用于React Native 0.56.0及以上版本

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;

对于早期版本的React Native,您只需要第二行代码,但两行代码都不会有害。第一行代码只是为了防止Text组件没有defaultProps,这种情况适用于React Native 0.56.0及以上版本。

将上述代码添加到React Native应用程序的入口文件中(通常为index.jsapp.jsmain.js),以将此属性应用于应用程序中的所有Text组件。

此属性仅影响Text组件,您可能希望将相同的更改应用于TextInput,可以使用类似的代码片段:

TextInput.defaultProps = TextInput.defaultProps || {};
TextInput.defaultProps.allowFontScaling = false;

请注意,某些组件不会遵循字体缩放设置,例如:AlertPickerIOSDatePickerIOSTabBarIOSSegmentedControlIOS,因为它们都是本地绘制的,不依赖于 Text 组件。


3
虽然有些黑客风格,但仍然非常聪明。我正在使用它。 - Kaiwen Huang
@KiritModi 我认为Alert是完全本地渲染的——所以我想你无法控制模态框内文本的渲染方式。相反,您需要实现自己的提示组件。 - levi
11
如果你有些想知道在哪里实现这个功能,就把上面的代码放在~/index.js文件中导入语句的下方。确保还要导入Text组件到RN中。顺便说一下,我正在运行RN 0.57.8版本。 - Mix Master Mike
Text.defaultProps有时可能未定义,因此最好使用:Text.defaultProps = Text.defaultProps || {}。它可以处理两种情况。 - dphaener
@dphaener 原始代码检查了 Text.defaultProps 是否未定义。 - levi

44

对于 React Native 0.58+ 版本:

保持字体缩放是最好的,但你可以通过使用 Text 组件的新属性 maxFontSizeMultiplier 来限制它。

对于 React Native 0.56+ 版本,请使用 Levi 的答案

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;

对于React Native 0.55及以下版本

在应用程序的开头(例如main.js或app.js等)添加Text.defaultProps.allowFontScaling=false,以将此属性应用于整个应用程序中的所有Text组件。


当我将它添加到App.js的构造函数中时,我会收到错误提示,我漏掉了什么吗? - ROI
1
对我来说非常有效。 - nobane
@AnshulKoka 你能确认一下吗?我正在查看文档,没有看到有关默认属性和allowFontScalling的任何内容。 - A-J-A
2
@A-J-A 今天我刚从react-native 0.55.4升级到0.56.0,但Text.defaultProps变成了未定义。 - Anshuul Kai

13
When user increase full font size from setting 

增大设备字体大小不会破坏(样式方面)。

index.js file


import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import {Text, TextInput} from 'react-native';

AppRegistry.registerComponent(appName, () => App);

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

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

<CalendarStrip
    shouldAllowFontScaling={false}
/>

请注意,一些组件不会遵守字体缩放设置,例如:Alert、PickerIOS、DatePickerIOS、TabBarIOS、SegmentedControlIOS,因为它们都是本地绘制的,不依赖于Text组件。


5

虽然我有点晚了,但如果有人需要使用Typescript的答案,这里有一个:

interface TextWithDefaultProps extends Text {
  defaultProps?: { allowFontScaling?: boolean };
}

(Text as unknown as TextWithDefaultProps).defaultProps = {
   ...((Text as unknown as TextWithDefaultProps).defaultProps || {}),
   allowFontScaling: false,
 };

如果你想允许缩放但不要太多,你可以像这样调整这个解决方案:接口TextWithDefaultProps扩展了Text接口,其中包含defaultProps属性,该属性是一个对象,其中包含maxFontSizeMultiplier属性,它的值是一个数字。 (Text as unknown as TextWithDefaultProps).defaultProps = { ...((Text as unknown as TextWithDefaultProps).defaultProps || {}), maxFontSizeMultiplier: 1.1, }; - undefined

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

我将会尽力为您翻译以下内容,涉及到IT技术:在index.js的构造函数中,我保留了这段代码。它真的很有效。顺便说一句,我使用的是React Native版本0.59.9。"Original Answer"翻译成中文是"最初的回答"。

Text.defaultProps = Text.defaultProps || {} ; Text.defaultProps.allowFontScaling = false;这是等同于您的代码。 - A-J-A

1
创建一个<AppText>组件,并将其与您的预设一起使用,而不是使用原始组件,包括自己的默认设置,其中包括字体缩放为假。这样更好,因为您可以使用自己的API丰富它。
例如,我的AppText允许执行以下操作: <AppText id="some.translation.key" color="primary" size="l" underline italic bold/>

在某些情况下可能是您需要的,但如果您想要ReactNavigation限制在“headerRight”中使用的“MaterialCommunityIcons”的字体缩放,该怎么办?不幸的是,使用“<MaterialCommunityIcons name =”magnify“allowFontScaling = {false}“/>”无效。 - Wodin

1

对于webview,我们可以使用textZoom={100}属性来处理字体大小的变化,如果字体大小从移动设置中改变。

如果从react-native-webview导入。

<WebView
    textZoom={100}
    source={}/>

1
在另一个文件中,将实际的Text组件作为备份导入为ScaledText,然后重新定义Text,覆盖allowFontScaling属性。
export function Text(props) {
  return <ScaledText {...props} allowFontScaling={false} />;
}

然后,导入你本地定义的Text组件,而不是内置的React Native Text。如果你想优雅地仅在应用程序的某些部分禁用字体缩放,这也非常有用。

1

针对IOS

index.js

import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import {Text, TextInput} from 'react-native';

AppRegistry.registerComponent('appName', () => App);

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

请注意,像 Alert PickerIOS DatePickerIOS TabBarIOS SegmentedControlIOS 这样的一些组件不会遵守字体缩放设置,因为它们是本地绘制的,不依赖于文本组件。

对于安卓

import android.content.res.Configuration;
import android.util.DisplayMetrics;
import android.view.WindowManager;

public class MainApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    adjustFontScale(getResources().getConfiguration());
  }

  private void adjustFontScale(Configuration configuration) {
    configuration.fontScale = (float) 1.0;
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
    metrics.scaledDensity = configuration.fontScale * metrics.density;
    getBaseContext().getResources().updateConfiguration(configuration, metrics);
  }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接