react / react/react-native

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

Abierto
#56,309 1 comentario 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Needs: Triage :mag: Platform: iOS Type: New Architecture
Lenguaje dominante
C++
Estrellas
127k
Forks
25.3k
Merge medio
1 d 23 h
PR fusionados (30 d)
4

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza en React/Fabric/Surface/RCTFabricSurface.mm, en RCTFontSizeMultiplier(), después ejecuta la configuración vinculada de react-native-font-scaling-repro y reproduce el problema en su share extension. Verifica el cambio con componentes Text que usen fuentes personalizadas, fuentes del sistema y el comportamiento de Dynamic Type en una app extension. Se considera terminado cuando el texto con fuentes personalizadas es visible con el escalado correcto sin requerir allowFontScaling={false}.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
ios, objective-c, react-native
Área
mobile-dev
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
72/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.