You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中useFonts钩子在Android可用但iOS无法渲染的原因?

解决React Native(Expo)自定义字体在iOS 15.2无法渲染的问题

针对你遇到的Android正常、iOS 15.2无法渲染自定义字体的问题,以下是几个可行的排查和解决步骤:

1. 确认iOS字体的实际内部名称

iOS系统识别的字体名称可能和文件名不一致,比如Montserrat-Regular.ttf的内部名称可能是Montserrat Regular(不带连字符)。你可以通过两种方式确认:

  • 用Mac的「字体册」打开字体文件,查看顶部显示的正式名称
  • 在代码中打印可用字体列表验证:
import { Font } from 'expo-font';

// 在根组件加载字体后执行
Font.loadAsync({
  'Montserrat-Regular': require('./assets/fonts/Montserrat-Regular.ttf'),
}).then(() => {
  Font.getAvailableFonts().then(fonts => console.log('可用字体:', fonts));
});

找到对应字体的实际名称后,将useFonts中的key替换为该名称,同时Text组件的fontFamily属性也使用这个名称。

2. 全局统一加载字体,避免组件内重复加载

当前每个AppText组件都调用useFonts会导致重复加载字体,这在iOS上可能引发异常。建议将字体加载逻辑移到根组件(如App.js):

import { useFonts } from 'expo-font';
import AppLoading from 'expo-app-loading';
import { View } from 'react-native';

export default function App() {
  const [fontsLoaded] = useFonts({
    // 这里使用字体的实际内部名称
    'Montserrat Regular': require('./assets/fonts/Montserrat-Regular.ttf'),
    'Montserrat Medium': require('./assets/fonts/Montserrat-Medium.ttf'),
    // 其他字体...
  });

  if (!fontsLoaded) {
    return <AppLoading />;
  }

  return (
    <View>
      {/* 你的导航或页面组件 */}
    </View>
  );
}

之后AppText组件无需再处理字体加载,直接使用fontFamily即可。

3. 替换return null为加载占位

原代码中字体未加载完成时返回null,iOS可能因为布局突然变化导致渲染异常。可以替换为加载提示或占位组件:

if (!fontsLoaded) {
  return <Text style={{ fontSize: 16 }}>加载中...</Text>;
}

4. 确认app.json中配置了字体资源

确保app.json的expo.assets数组包含字体目录,让Expo正确打包字体到iOS项目:

{
  "expo": {
    "assets": ["./assets/fonts"],
    // 其他配置项...
  }
}

5. 检查依赖版本兼容性

确保expo-font版本与当前Expo SDK版本匹配,若版本过旧可能存在iOS 15.x的兼容问题,可执行以下命令升级:

expo install expo-font

内容的提问来源于stack exchange,提问作者Timotius Satrio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:10:31