Dynamic Type é um recurso integrado do iOS que altera automaticamente o tamanho da fonte no aplicativo de acordo com as configurações de sistema do usuário. O usuário define o tamanho de texto preferido em Ajustes → Tela e Brilho → Tamanho do Texto, e todos os aplicativos que suportam Dynamic Type se adaptam sem ações adicionais. De acordo com as Diretrizes de Interface Humana da Apple, 2024, o suporte ao Dynamic Type é um requisito obrigatório para publicação na App Store, pois é um elemento básico de acessibilidade na plataforma iOS.
Principais pontos
Dynamic Type é uma tecnologia do iOS introduzida no iOS 7 que permite que o texto em um aplicativo se ajuste automaticamente às configurações de tamanho de fonte do sistema. O usuário pode aumentar ou diminuir a fonte em todos os aplicativos de uma só vez — sem precisar alterar as configurações dentro de cada aplicativo individualmente.
De acordo com a Apple WWDC 2023, “Make Your App Visually Accessible”, mais de 40% dos usuários iOS alteram o tamanho da fonte em relação ao padrão. Para o grupo etário de 65+ anos, esse número chega a 70%. O Dynamic Type é um requisito obrigatório para a certificação de acessibilidade da App Store. A falta de suporte é motivo de rejeição durante a revisão.
Como funciona: o aplicativo usa UIFont.preferredFont(forTextStyle:) em vez de UIFont(name:size:). O iOS retorna automaticamente uma fonte escalada de acordo com a configuração atual do sistema. Quando o tamanho muda nas configurações, o iOS gera uma notificação UIContentSizeCategory.didChangeNotification — o aplicativo deve recalcular o layout.
O Dynamic Type apareceu no iOS 7 junto com o design plano. O iOS 10 adicionou suporte para fontes personalizadas via UIFontMetrics. O iOS 11 introduziu níveis de acessibilidade (até AccessibilityXXXL). O iOS 15 adicionou Dynamic Type no SwiftUI com suporte automático. A cada lançamento, a Apple reforça os requisitos: a partir do iOS 17, aplicativos sem suporte a Dynamic Type recebem um aviso ao serem enviados ao App Store Connect.
O iOS fornece 8 estilos de texto, cada um com tamanho e peso predefinidos para a configuração padrão:
| Estilo | Constante | Tamanho (L) | Propósito |
|---|---|---|---|
| Large Title | .largeTitle | 34px | Título principal da tela |
| Title 1 | .title1 | 28px | Cabeçalho de seção |
| Title 2 | .title2 | 22px | Subtítulo |
| Title 3 | .title3 | 20px | Título de cartão |
| Headline | .headline | 17px (negrito) | Negrito para ênfase |
| Body | .body | 17px | Texto principal |
| Callout | .callout | 16px | Texto complementar |
| Caption 1 | .caption1 | 12px | Legenda de imagem |
| Caption 2 | .caption2 | 11px | Legenda pequena |
| Footnote | .footnote | 13px | Nota de rodapé |
Usar o estilo correto não é apenas uma questão de “aparência”. UIFont.TextStyle.body no modo AccessibilityXXXL pode atingir 53px. Se um aplicativo usa uma fonte fixa de 17px para o body, o texto se torna ilegível para usuários que aumentaram o tamanho da fonte.
O Dynamic Type não apenas escala — ele preserva a hierarquia visual. Large Title é sempre maior que Title 1, que é maior que Body, independentemente do nível de escala. Os coeficientes de escala variam: os títulos escalam de forma mais agressiva que o texto principal, para que a hierarquia seja mantida mesmo em níveis de acessibilidade.
O iOS suporta 11 níveis de escala de texto, divididos em duas categorias:
A diferença entre XS e AccessibilityXXXL para o estilo body varia de 14px a 53px — quase 4×. Um layout projetado para 17px quebra completamente em 53px: o texto transborda, os botões se sobrepõem, as células colidem.
Verificar a categoria atual no código:
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// Habilitar layout alternativo
}
A categoria de tamanho de texto está disponível via traitCollection.uiContentSizeCategory. Quando a configuração do sistema muda, o iOS chama traitCollectionDidChange em todas as UIView. Neste método, você precisa atualizar as fontes e recalcular o layout. O SwiftUI faz isso automaticamente — o UIKit requer assinatura manual.
Para UICollectionView, use UICollectionViewCompositionalLayout — ele ajusta automaticamente o número de colunas à largura da tela e ao tamanho do texto. Em níveis de acessibilidade, mude de um layout de duas colunas para uma coluna única para que o texto não seja truncado e os elementos não se sobreponham. Use layout condicional: para largura regular — duas colunas, para compacto ou acessibilidade — uma coluna.
A implementação básica no UIKit — UIFont.preferredFont(forTextStyle:). Este método retorna uma fonte escalada de acordo com a configuração atual do sistema:
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
Para fontes personalizadas, use UIFontMetrics:
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
.scaledFont(for: customFont)
// Monitoramento de mudanças de tamanho
NotificationCenter.default.addObserver(
self,
selector: #selector(preferredContentSizeChanged),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
Para UILabel no Interface Builder, basta definir a fonte como um estilo de texto e ativar “Automatically Adjusts Font”. Para fontes personalizadas, o Interface Builder não suporta UIFontMetrics — apenas via código.
O UIFontMetrics usa a mesma curva de escala que o preferredFont. Você pode especificar fromTextStyle: .body, .headline, etc. Cada estilo tem seu próprio coeficiente de escala. Body escala moderadamente, Large Title escala agressivamente. Se sua fonte personalizada é usada para texto principal, use .body.
No SwiftUI, o suporte a Dynamic Type é incorporado por padrão. Todos os modificadores do sistema (.font(.body), .font(.title)) escalam automaticamente. O desenvolvedor não precisa chamar UIFont.preferredFont.
Exemplo:
Text("Texto principal")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
Para escalas personalizadas, use DynamicTypeSize:
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
Text("Texto adaptativo")
.font(.body)
.padding(dynamicTypeSize <= .large ? 8 : 16)
}
O SwiftUI atualiza automaticamente a visualização quando o tamanho do texto do sistema muda — sem necessidade de assinaturas adicionais de notificação.
O modificador .font(.body) funciona apenas para a fonte do sistema. Para fontes personalizadas no SwiftUI, use Font.custom com UIFontMetrics internamente. A partir do iOS 16, o SwiftUI suporta DynamicTypeSize no @Environment, permitindo adaptar padding e layout.
Auto Layout é um pré-requisito para o suporte a Dynamic Type. Larguras e alturas fixas (>=, <=) quebram em tamanhos de acessibilidade. Use intrinsicContentSize para UILabel — ele calcula automaticamente a altura para o tamanho de fonte atual.
Regras de layout adaptativo:
Para textos longos (por exemplo, artigos, termos de uso), defina minimumScaleFactor no UILabel — isso reduz o texto como último recurso quando o Auto Layout não consegue acomodar o conteúdo. Um valor de 0.5 significa que a fonte pode reduzir para 50% do tamanho preferido.
Exemplo de ajuste de padding conforme a categoria de tamanho:
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)
Truncamento de texto — UILabel com numberOfLines = 1 e largura fixa trunca o texto em AccessibilityXL. Solução: numberOfLines = 0 e constraint trailing. Sobreposição de elementos — botões com altura fixa se sobrepõem. Solução: UIStackView com espaçamento automático. Conteúdo fora da tela — ScrollView é obrigatório para níveis de acessibilidade.
O Simulador do Xcode permite alterar o tamanho do texto: no menu do simulador, vá em Settings → Accessibility → Display & Text Size → Larger Text. Alterne entre todos os 11 níveis e verifique se o texto não é truncado, os botões estão acessíveis e o layout não quebra.
Para testes automatizados, use a configuração contentSizeCategory no XCUIApplication:
func testAccessibilitySizes() {
let app = XCUIApplication()
app.launchArguments += [
"-UIPreferredContentSizeCategoryName",
"UICTContentSizeCategoryAccessibilityXXXL"
]
app.launch()
app.scrollViews.buttons["Enviar"].tap()
XCTAssertTrue(app.staticTexts["Formulário enviado"]
.waitForExistence(timeout: 5))
}
O XCUITest com diferentes launchArguments permite verificar todos os níveis de escala no CI. Não se esqueça de testar as categorias de acessibilidade separadamente — são as que mais frequentemente quebram o layout. Segundo a Apple, 70% dos bugs do Dynamic Type são encontrados especificamente em níveis de acessibilidade, porque os desenvolvedores testam apenas tamanhos padrão.
O Xcode Accessibility Inspector mostra quais fontes o elemento selecionado usa — fixas ou escaláveis. Se o elemento não responder às alterações de tamanho de texto no simulador, uma fonte fixa está sendo usada. Substitua por UIFont.preferredFont ou UIFontMetrics.
Perguntas frequentes
É a escala automática de texto em um aplicativo de acordo com as configurações de tamanho do sistema. O usuário altera o tamanho nas Configurações — todos os aplicativos compatíveis se adaptam sem intervenção do desenvolvedor.
Não. Para fontes personalizadas, use UIFontMetrics(scaledFont:). Este método escala qualquer fonte em relação ao estilo de texto especificado, mantendo as proporções.
11 níveis: 5 padrão (XS, S, M, L, XL) e 6 níveis de acessibilidade (de AccessibilityXL a AccessibilityXXXXXL). O tamanho da fonte body pode variar de 14px a 53px.
No UIKit através de UIContentSizeCategory.didChangeNotification. No SwiftUI, use @Environment(\.dynamicTypeSize) — a visualização é atualizada automaticamente quando a configuração do sistema muda.
Usuários com fonte aumentada verão texto truncado, elementos sobrepostos e botões quebrados. O aplicativo pode ser rejeitado na revisão da App Store por violar os requisitos de acessibilidade.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também