Dynamic Type es una función integrada de iOS que cambia automáticamente el tamaño de la fuente en una aplicación según la configuración del sistema del usuario. El usuario establece su tamaño de texto preferido en Configuración → Pantalla y brillo → Tamaño del texto, y todas las aplicaciones compatibles con Dynamic Type se adaptan sin acciones adicionales. Según las Apple Human Interface Guidelines, 2024, el soporte de Dynamic Type es un requisito obligatorio para publicar en App Store, ya que es un elemento básico de accesibilidad en la plataforma iOS.
Puntos clave
Dynamic Type es una tecnología de iOS introducida en iOS 7 que permite que el texto en una aplicación se ajuste automáticamente a la configuración del tamaño de fuente del sistema. El usuario puede aumentar o disminuir la fuente en todas las aplicaciones a la vez — sin tener que cambiar la configuración dentro de cada aplicación individualmente.
Según Apple WWDC 2023, “Make Your App Visually Accessible”, más del 40% de los usuarios de iOS cambian el tamaño de la fuente respecto al estándar. Para el grupo de edad de 65+ años, esta cifra alcanza el 70%. Dynamic Type es un requisito obligatorio para la certificación de accesibilidad de App Store. La falta de soporte es un motivo de rechazo durante la revisión.
Cómo funciona: la aplicación usa UIFont.preferredFont(forTextStyle:) en lugar de UIFont(name:size:). iOS devuelve automáticamente una fuente escalada según la configuración actual del sistema. Cuando el tamaño cambia en la configuración, iOS genera una notificación UIContentSizeCategory.didChangeNotification — la aplicación debe recalcular el diseño.
Dynamic Type apareció en iOS 7 junto con el diseño plano. iOS 10 añadió soporte para fuentes personalizadas mediante UIFontMetrics. iOS 11 introdujo niveles de accesibilidad (hasta AccessibilityXXXL). iOS 15 añadió Dynamic Type en SwiftUI con soporte automático. Con cada versión, Apple refuerza los requisitos: a partir de iOS 17, las aplicaciones sin soporte de Dynamic Type reciben una advertencia al cargarse en App Store Connect.
iOS proporciona 8 estilos de texto, cada uno con un tamaño y grosor predefinidos para la configuración predeterminada:
| Estilo | Constante | Tamaño (L) | Propósito |
|---|---|---|---|
| Large Title | .largeTitle | 34px | Título principal de la pantalla |
| Title 1 | .title1 | 28px | Encabezado de sección |
| Title 2 | .title2 | 22px | Subencabezado |
| Title 3 | .title3 | 20px | Título de tarjeta |
| Headline | .headline | 17px (negrita) | Negrita para énfasis |
| Body | .body | 17px | Texto principal |
| Callout | .callout | 16px | Texto complementario |
| Caption 1 | .caption1 | 12px | Pie de imagen |
| Caption 2 | .caption2 | 11px | Pie pequeño |
| Footnote | .footnote | 13px | Nota al pie |
Usar el estilo correcto no es solo cuestión de “apariencia”. UIFont.TextStyle.body en modo AccessibilityXXXL puede alcanzar los 53px. Si una aplicación usa una fuente fija de 17px para el body, el texto se vuelve ilegible para los usuarios que han aumentado el tamaño de la fuente.
Dynamic Type no solo escala — preserva la jerarquía visual. Large Title siempre es más grande que Title 1, que es más grande que Body, independientemente del nivel de escala. Los coeficientes de escala varían: los encabezados escalan de forma más agresiva que el texto principal, para que la jerarquía se mantenga incluso en niveles de accesibilidad.
iOS admite 11 niveles de escala de texto, divididos en dos categorías:
La diferencia entre XS y AccessibilityXXXL para el estilo body va de 14px a 53px — casi 4×. Un diseño pensado para 17px se rompe por completo a 53px: el texto se desborda, los botones se superponen, las celdas chocan entre sí.
Verificar la categoría actual en código:
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// Habilitar diseño alternativo
}
La categoría de tamaño de texto está disponible mediante traitCollection.uiContentSizeCategory. Cuando cambia la configuración del sistema, iOS llama a traitCollectionDidChange en todas las UIView. En este método, debes actualizar las fuentes y recalcular el diseño. SwiftUI lo hace automáticamente — UIKit requiere suscripción manual.
Para UICollectionView, usa UICollectionViewCompositionalLayout — ajusta automáticamente el número de columnas al ancho de la pantalla y al tamaño del texto. En niveles de accesibilidad, cambia de un diseño de dos columnas a una columna única para que el texto no se trunque y los elementos no se superpongan. Usa diseño condicional: para ancho regular — dos columnas, para compacto o accesibilidad — una columna.
La implementación básica en UIKit — UIFont.preferredFont(forTextStyle:). Este método devuelve una fuente escalada según la configuración actual del sistema:
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
Para fuentes personalizadas, usa UIFontMetrics:
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
.scaledFont(for: customFont)
// Seguimiento de cambios de tamaño
NotificationCenter.default.addObserver(
self,
selector: #selector(preferredContentSizeChanged),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
Para UILabel en Interface Builder, simplemente establece la fuente como un estilo de texto y activa “Automatically Adjusts Font”. Para fuentes personalizadas, Interface Builder no admite UIFontMetrics — solo mediante código.
UIFontMetrics usa la misma curva de escala que preferredFont. Puedes especificar fromTextStyle: .body, .headline, etc. Cada estilo tiene su propio coeficiente de escala. Body escala moderadamente, Large Title escala de forma agresiva. Si tu fuente personalizada se usa para texto principal, usa .body.
En SwiftUI, el soporte de Dynamic Type está integrado por defecto. Todos los modificadores del sistema (.font(.body), .font(.title)) escalan automáticamente. El desarrollador no necesita llamar a UIFont.preferredFont.
Ejemplo:
Text("Texto principal")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
Para escalas personalizadas, usa DynamicTypeSize:
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
Text("Texto adaptativo")
.font(.body)
.padding(dynamicTypeSize <= .large ? 8 : 16)
}
SwiftUI actualiza automáticamente la vista cuando cambia el tamaño del texto del sistema — no se necesitan suscripciones adicionales a notificaciones.
El modificador .font(.body) solo funciona para la fuente del sistema. Para fuentes personalizadas en SwiftUI, usa Font.custom con UIFontMetrics internamente. A partir de iOS 16, SwiftUI admite DynamicTypeSize en @Environment, lo que permite adaptar el padding y la disposición.
Auto Layout es un requisito previo para el soporte de Dynamic Type. Los anchos y alturas fijos (>=, <=) se rompen en tamaños de accesibilidad. Usa intrinsicContentSize para UILabel — calcula automáticamente la altura para el tamaño de fuente actual.
Reglas de diseño adaptativo:
Para textos largos (por ejemplo, artículos, términos de uso), establece minimumScaleFactor en UILabel — esto reduce el texto como último recurso cuando Auto Layout no puede acomodar el contenido. Un valor de 0.5 significa que la fuente puede reducirse al 50% del tamaño preferido.
Ejemplo de ajuste de padding según la categoría de tamaño:
let isAccessibility = traitCollection
.preferredContentSizeCategory.isAccessibilityCategory
stackView.spacing = isAccessibility ? 16 : 8
button.contentEdgeInsets = isAccessibility
? UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 24)
: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
Truncamiento de texto — UILabel con numberOfLines = 1 y ancho fijo trunca el texto en AccessibilityXL. Solución: numberOfLines = 0 y constraint trailing. Superposición de elementos — los botones con altura fija se superponen. Solución: UIStackView con spacing automático. Contenido fuera de pantalla — ScrollView es obligatorio para niveles de accesibilidad.
El Simulador de Xcode permite cambiar el tamaño del texto: en el menú del simulador, ve a Settings → Accessibility → Display & Text Size → Larger Text. Cambia entre los 11 niveles y verifica que el texto no se trunque, los botones sean accesibles y el diseño no se rompa.
Para pruebas automatizadas, usa la configuración contentSizeCategory en XCUIApplication:
func testAccessibilitySizes() {
let app = XCUIApplication()
app.launchArguments += [
"-UIPreferredContentSizeCategoryName",
"UICTContentSizeCategoryAccessibilityXXXL"
]
app.launch()
app.scrollViews.buttons["Enviar"].tap()
XCTAssertTrue(app.staticTexts["Formulario enviado"]
.waitForExistence(timeout: 5))
}
XCUITest con diferentes launchArguments permite verificar todos los niveles de escala en CI. No olvides probar las categorías de accesibilidad por separado — son las que más a menudo rompen el diseño. Según Apple, el 70% de los errores de Dynamic Type se encuentran específicamente en niveles de accesibilidad, porque los desarrolladores solo prueban tamaños estándar.
Xcode Accessibility Inspector muestra qué fuentes usa el elemento seleccionado — fijas o escalables. Si el elemento no responde a los cambios de tamaño de texto en el simulador, se está usando una fuente fija. Reemplázala con UIFont.preferredFont o UIFontMetrics.
Preguntas frecuentes
Es el escalado automático del texto en una aplicación según la configuración del tamaño del sistema. El usuario cambia el tamaño en Configuración — todas las aplicaciones compatibles se adaptan sin intervención del desarrollador.
No. Para fuentes personalizadas, usa UIFontMetrics(scaledFont:). Este método escala cualquier fuente respecto al estilo de texto especificado, preservando las proporciones.
11 niveles: 5 estándar (XS, S, M, L, XL) y 6 niveles de accesibilidad (desde AccessibilityXL hasta AccessibilityXXXXXL). El tamaño de la fuente body puede variar de 14px a 53px.
En UIKit mediante UIContentSizeCategory.didChangeNotification. En SwiftUI, usa @Environment(\.dynamicTypeSize) — la vista se actualiza automáticamente cuando cambia la configuración del sistema.
Los usuarios con fuente aumentada verán texto truncado, elementos superpuestos y botones rotos. La aplicación puede ser rechazada en la revisión de App Store por violar los requisitos de accesibilidad.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también