Text with custom fonts is invisible in iOS App Extensions (Fabric / New Architecture)
还没有人认领这个 Issue。
- 主要语言
- C++
- 星标
- 127k
- 派生
- 25.3k
- 平均合并
- 1 天 23 小时
- 30 天内合并 PR
- 4
描述
When using React Native 0.84+ with the new architecture in an iOS App Extension (Share Extension, Action Extension, etc.), all <Text> components that use a custom fontFamily are invisible. Text using the system font renders fine, but with the wrong size.
Setting allowFontScaling={false} on individual <Text> components works around the issue.
Root Cause
RCTFontSizeMultiplier() in React/Fabric/Surface/RCTFabricSurface.mm calls:
return mapping[RCTSharedApplication().preferredContentSizeCategory].floatValue;
In App Extensions, RCTSharedApplication() returns nil (because UIApplication.sharedApplication is unavailable in extensions). This causes:
nil.preferredContentSizeCategory→nilmapping[nil]→nilnil.floatValue→0.0
This 0.0 is stored as layoutContext.fontSizeMultiplier, which propagates to all text measurement:
// In RCTFontWithFontProperties (prebuilt binary):
CGFloat effectiveFontSize = fontProperties.sizeMultiplier * fontProperties.size;
// effectiveFontSize = 0.0 * 14.0 = 0.0
System fonts survive because [UIFont systemFontOfSize:0] returns a 12pt default font. But custom fonts fail because [UIFont fontWithName:@"CustomFont" size:0] returns nil, falling through to a Helvetica fallback with incorrect metrics — resulting in zero-sized text layout.
Proposed Fix
Replace RCTSharedApplication().preferredContentSizeCategory with UITraitCollection.currentTraitCollection.preferredContentSizeCategory, which works in both apps and extensions:
// Before (broken in extensions):
return mapping[RCTSharedApplication().preferredContentSizeCategory].floatValue;
// After (works everywhere):
NSString *category;
if (!RCTRunningInAppExtension()) {
category = RCTSharedApplication().preferredContentSizeCategory;
} else {
category = UITraitCollection.currentTraitCollection.preferredContentSizeCategory;
}
return mapping[category ?: UIContentSizeCategoryLarge].floatValue;
This also correctly handles Dynamic Type accessibility settings in extensions, which the current code silently ignores.
Workarounds
Per-component (JS)
<Text style={{ fontFamily: 'Inter-Regular' }} allowFontScaling={false}>
This text will be visible
</Text>
Native swizzle (ObjC++)
Swizzle RCTFabricSurface._updateLayoutContext to correct fontSizeMultiplier from 0 to 1.0 after the original implementation sets it. See ShareExtensionReactHelper.mm in the main project for a working implementation.
Steps to reproduce
- Clone this https://github.com/erkie/react-native-font-scaling-repro
npm install && cd ios && bundle exec pod install && cd ..npm run ios- Open Safari, navigate to any page, tap Share → select "FontScalingReproShareExtension"
React Native Version
0.84.1
Affected Platforms
Runtime - iOS
Areas
Fabric - The New Renderer
Output of npx @react-native-community/cli info
System:
OS: macOS 26.3.1
CPU: (14) arm64 Apple M4 Pro
Memory: 172.81 MB / 48.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 24.13.0
path: /Users/thingtesting/.local/state/fnm_multishells/75626_1775109555064/bin/node
Yarn: Not Found
npm:
version: 11.6.2
path: /Users/thingtesting/.local/state/fnm_multishells/75626_1775109555064/bin/npm
Watchman:
version: 2025.05.26.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /Users/thingtesting/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.0
- iOS 26.0
- macOS 26.0
- tvOS 26.0
- visionOS 26.0
- watchOS 26.0
Android SDK:
API Levels:
- "34"
- "35"
- "36"
Build Tools:
- 34.0.0
- 35.0.0
- 36.0.0
System Images:
- android-34 | Google APIs ARM 64 v8a
- android-34 | Google APIs Intel x86_64 Atom
Android NDK: Not Found
IDEs:
Android Studio: 2025.2 AI-252.27397.103.2522.14617522
Xcode:
version: 26.0/17A324
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.16
path: /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home/bin/javac
Ruby:
version: 3.4.5
path: /Users/thingtesting/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.1.0
wanted: 20.1.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.84.1
wanted: 0.84.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
Please review screenshots
MANDATORY Reproducer
https://github.com/erkie/react-native-font-scaling-repro
Screenshots and Videos
Inside app, works with custom fonts
Inside share extension, invisible texts
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 React/Fabric/Surface/RCTFabricSurface.mm 中的 RCTFontSizeMultiplier() 开始,然后运行链接的 react-native-font-scaling-repro 设置,并在其 share extension 中重现问题。使用自定义字体的 Text 组件、系统字体以及 app extension 中的 Dynamic Type 行为验证此更改。当自定义字体文本能够以正确的缩放比例显示,且不需要 allowFontScaling={false} 时,即表示完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- ios, objective-c, react-native
- 领域
- mobile-dev
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 冷清
- 描述清晰度
- 描述清楚
- 新手友好度
- 72/100