Expo Eject后iOS报Unrecognized Font Family(montserrat)错误
Expo SDK45 Eject后iOS启动报「Unrecognised font family」错误
问题背景
- 基于Expo SDK 45开发的应用执行Eject操作后,iOS端构建成功、可在真机正常安装启动,但启动瞬间抛出
Unrecognised font family错误。 - 项目依赖
@expo-google-fonts/montserrat字体包,原有字体加载实现代码如下:
//Other Depedencies are here import { Montserrat_100Thin, Montserrat_200ExtraLight, Montserrat_300Light, Montserrat_400Regular, Montserrat_400Regular_Italic, Montserrat_500Medium, Montserrat_600SemiBold, Montserrat_700Bold, Montserrat_800ExtraBold, useFonts } from '@expo-google-fonts/montserrat'; const App = (): JSX.Element => { const [fontsLoaded] = useFonts({ Montserrat_100Thin, Montserrat_200ExtraLight, Montserrat_300Light, Montserrat_400Regular_Italic, Montserrat_400Regular, Montserrat_500Medium, Montserrat_600SemiBold, Montserrat_700Bold, Montserrat_800ExtraBold }); React.useEffect(() => { async function prepare(): Promise<void> { try { await SplashScreen.preventAutoHideAsync(); } catch (e) { console.warn(e); } } void prepare(); }, []); const onLayoutRootView = useCallback(async () => { if (fontsLoaded) { await SplashScreen.hideAsync(); } }, [fontsLoaded]); return ( <ContentOfTheApp/> ); };
- 已完成的配置项:
- 字体文件已添加至iOS项目结构
- 字体已在
info.plist中完成声明 - 字体文件已加入Copy Bundle Resources列表
- 已尝试的修复操作:重装pods依赖、清理构建文件夹、更新
@expo-google-fonts与expo-font依赖版本,问题仍未解决。
修复方案
按以下顺序排查修复:
- 补全字体加载状态拦截逻辑
现有代码存在两个明显逻辑遗漏:
- 定义了
onLayoutRootView回调但未绑定到根视图,SplashScreen无法在字体加载完成后正确隐藏 - 未判断
fontsLoaded状态就直接渲染业务组件,会导致组件渲染时字体资源还未完成注册,直接触发字体找不到的错误。
修改后的根组件逻辑如下:
import { View } from 'react-native'; // 其余原有依赖保持不变 const App = (): JSX.Element => { const [fontsLoaded] = useFonts({ Montserrat_100Thin, Montserrat_200ExtraLight, Montserrat_300Light, Montserrat_400Regular_Italic, Montserrat_400Regular, Montserrat_500Medium, Montserrat_600SemiBold, Montserrat_700Bold, Montserrat_800ExtraBold }); React.useEffect(() => { async function prepare(): Promise<void> { try { await SplashScreen.preventAutoHideAsync(); } catch (e) { console.warn(e); } } prepare(); }, []); const onLayoutRootView = useCallback(async () => { if (fontsLoaded) { await SplashScreen.hideAsync(); } }, [fontsLoaded]); // 字体未加载完成时阻断业务内容渲染 if (!fontsLoaded) return null; return ( <View style={{flex: 1}} onLayout={onLayoutRootView}> <ContentOfTheApp/> </View> ); };
- 校验iOS端字体实际注册名称
如果补全逻辑后仍报错,需要核对字体在iOS系统中的实际注册名,避免名称不匹配问题:
- 打开iOS项目下的
AppDelegate.m文件,在didFinishLaunchingWithOptions方法中加入如下代码:
for (NSString* family in [UIFont familyNames]) { NSLog(@"Font family: %@", family); for (NSString* name in [UIFont fontNamesForFamilyName: family]) { NSLog(@"Font name: %@", name); } }
- 重新运行应用,在Xcode控制台搜索Montserrat,拿到字体的实际PostScript名称,替换代码中StyleSheet里使用的
fontFamily值即可。部分字体的实际注册名和文件名、@expo-google-fonts导出的常量名存在大小写或后缀差异,必须以系统打印的实际注册名为准。
- 校验Target关联配置
打开Xcode,选中所有导入的Montserrat字体文件,在右侧属性面板的Target Membership板块,确认勾选了应用的主Target。仅将字体加入Copy Bundle Resources列表偶尔会出现Target关联遗漏的问题,手动勾选后重新构建即可。
备注:原提问标题存在拼写错误已修正。
内容的提问来源于stack exchange,提问作者Loic L
相关产品推荐
相关产品推荐

