react / react/react-native

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

Aperta
#56,309 1 commento 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Needs: Triage :mag: Platform: iOS Type: New Architecture
Lingua principale
C++
Stelle
127k
Fork
25.3k
Merge medio
1g 23h
PR unite (30g)
4

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in React/Fabric/Surface/RCTFabricSurface.mm, in RCTFontSizeMultiplier(), quindi esegui il setup collegato di react-native-font-scaling-repro e riproduci il problema nella relativa share extension. Verifica la modifica con componenti Text che usano font personalizzati, font di sistema e il comportamento di Dynamic Type in un’app extension. Il lavoro è completato quando il testo con font personalizzati è visibile con il ridimensionamento corretto senza richiedere allowFontScaling={false}.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
ios, objective-c, react-native
Ambito
mobile-dev
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
72/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.