react / react/react-native

Text with custom fonts is invisible in iOS App Extensions (Fabric / New Architecture)

オープン
#56,309 コメント 1 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Needs: Triage :mag: Platform: iOS Type: New Architecture
主要言語
C++
スター
127k
フォーク
25.3k
平均マージ
1日 23時間
マージ済み PR(30日)
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:

  1. nil.preferredContentSizeCategorynil
  2. mapping[nil]nil
  3. nil.floatValue0.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
  1. Clone this https://github.com/erkie/react-native-font-scaling-repro
  2. npm install && cd ios && bundle exec pod install && cd ..
  3. npm run ios
  4. 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
Image

Inside share extension, invisible texts
Image

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. 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

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。