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
相关产品推荐
相关产品推荐

