react / react/react-native

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

Ouverte
#56,309 1 commentaire 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Needs: Triage :mag: Platform: iOS Type: New Architecture
Langage dominant
C++
Étoiles
127k
Forks
25.3k
Merge moyen
1 j 23 h
PR mergées (30 j)
4

Description

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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans React/Fabric/Surface/RCTFabricSurface.mm, au niveau de RCTFontSizeMultiplier(), puis exécutez la configuration liée de react-native-font-scaling-repro et reproduisez le problème dans son extension de partage. Vérifiez la modification avec des composants Text utilisant des polices personnalisées, les polices système et le comportement de Dynamic Type dans une extension d’app. C’est terminé lorsque le texte utilisant une police personnalisée est visible avec une mise à l’échelle correcte sans nécessiter allowFontScaling={false}.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
ios, objective-c, react-native
Domaine
mobile-dev
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Clairement spécifiée
Accessibilité débutants
72/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.