alejototaro.dev

react-native-font-alias: fuentes custom en iOS sin sufrir

Una librería para usar nombres de archivo como fontFamily en iOS, sin tener que buscar PostScript names.

| 2 min
react-nativeiosfontsopen-source

El problema

Si trabajás con React Native y fuentes custom, probablemente ya te pasó: agregás MiFuente-Regular.ttf al proyecto, la linkeás, y en Android funciona perfecto con fontFamily: 'MiFuente-Regular'. Pero en iOS no aparece.

El tema es que iOS no resuelve fuentes por nombre de archivo. Usa el PostScript name, que puede ser completamente distinto al archivo. Arima-Regular.ttf podría tener como PostScript name ArimaKoshi-Regular, y no hay forma de saberlo sin abrir Font Book o loguear todas las fuentes disponibles.

Esto lo sufrimos en cada proyecto. Cada vez que el equipo de diseño cambiaba una fuente, había que ir a buscar el PostScript name real, actualizar los estilos, y rezar que no hubiera otro nombre raro escondido.

La solución

Publiqué react-native-font-alias, una librería que te deja registrar alias para que fontFamily funcione con los nombres de archivo en iOS, igual que en Android.

npm install react-native-font-alias
cd ios && pod install

Después, al inicio de tu app (antes de que se renderice cualquier componente):

import { registerFontAliases } from 'react-native-font-alias';

registerFontAliases({
  'MiFuente-Regular': 'PostScriptNameReal-Regular',
  'MiFuente-Bold': 'PostScriptNameReal-Bold',
});

Y listo. A partir de ahí podés usar fontFamily: 'MiFuente-Regular' en tus estilos y funciona en ambas plataformas.

Cómo funciona por dentro

En iOS, la librería hace method swizzling sobre UIFont.fontWithName:size:. Cada vez que React Native (o cualquier cosa) pide cargar una fuente por nombre, el método intercepta la llamada, revisa si hay un alias registrado, y si lo hay, sustituye el nombre por el PostScript name real.

En Android no hace nada — es un no-op. Android ya resuelve por nombre de archivo, así que no necesita intervención.

El acceso al diccionario de alias es thread-safe con @synchronized y el swizzling se hace una sola vez con dispatch_once.

Cómo encontrar el PostScript name

Si no sabés cuál es el PostScript name de tu fuente, en macOS abrí Font Book, seleccioná la fuente y andá a Vista > Mostrar información de fuente.

O desde Xcode, logueá todas las fuentes disponibles:

for (NSString *family in [UIFont familyNames]) {
  for (NSString *name in [UIFont fontNamesForFamilyName:family]) {
    NSLog(@"%@", name);
  }
}

Compatibilidad

  • React Native >= 0.71
  • Soporta tanto la arquitectura vieja (Bridge) como la nueva (TurboModules)
  • iOS y Android

npmjs.com/package/react-native-font-alias

El repo está en github.com/Atotaro98/react-native-font-alias — cualquier issue o PR es bienvenido.