Dynamic Type: conceitos-chave, estilos de texto e como funciona no iOS

Autor: IT Sectr Publicado: 2026-05-16 Tempo de leitura: 9 min

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 — um mecanismo do iOS para escalar automaticamente o texto de acordo com as configurações de tamanho de fonte do sistema
  • O suporte é fornecido através de estilos de texto (UIFont.TextStyle) — body, headline, caption, title e outros
  • O sistema suporta 11 níveis de escala, de XSmall a AccessibilityXXXL
  • Para fontes personalizadas, usa-se o método UIFontMetrics, que escala qualquer fonte em relação ao estilo body
  • O layout deve ser adaptativo — UIStackView, Auto Layout e alturas dinâmicas de células são obrigatórios

O que é Dynamic Type no iOS

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.

Histórico do Dynamic Type

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.

Estilos de texto UIFont.TextStyle

O iOS fornece 8 estilos de texto, cada um com tamanho e peso predefinidos para a configuração padrão:

EstiloConstanteTamanho (L)Propósito
Large Title.largeTitle34pxTítulo principal da tela
Title 1.title128pxCabeçalho de seção
Title 2.title222pxSubtítulo
Title 3.title320pxTítulo de cartão
Headline.headline17px (negrito)Negrito para ênfase
Body.body17pxTexto principal
Callout.callout16pxTexto complementar
Caption 1.caption112pxLegenda de imagem
Caption 2.caption211pxLegenda pequena
Footnote.footnote13pxNota 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.

Hierarquia visual através de estilos

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.

Níveis de escala

O iOS suporta 11 níveis de escala de texto, divididos em duas categorias:

  • Tamanhos padrão (5 níveis): XS, S, M, L (padrão), XL
  • Tamanhos de acessibilidade (6 níveis): accessibilityXL, accessibilityXXL, accessibilityXXXL, accessibilityXXXXL, accessibilityXXXXXL, accessibilityXXXXXXL

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:

swift
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
    // Habilitar layout alternativo
}

traitCollection e tamanho do texto

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.

Implementação no UIKit

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:

swift
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)

Para fontes personalizadas, use UIFontMetrics:

swift
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.

UIFontMetrics e curva de escala

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.

Dynamic Type no SwiftUI

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:

swift
Text("Texto principal")
    .font(.body)
    .lineLimit(nil)
    .minimumScaleFactor(0.5)

Para escalas personalizadas, use DynamicTypeSize:

swift
@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.

Limitando Dynamic Type no SwiftUI

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.

Adaptação do layout para fontes grandes

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:

  • UIStackView com distribution = fill e spacing >= 8 — os elementos serão movidos para a próxima linha
  • UITableViewCell com automaticDimension — a altura da célula se ajusta ao conteúdo
  • numberOfLines = 0 no UILabel — o texto não é truncado, mas quebrado
  • Botões com edgeInsets — adicione padding em níveis de acessibilidade via traitCollection.preferredContentSizeCategory

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:

swift
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)

Problemas típicos de layout em níveis de acessibilidade

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.

Teste do Dynamic Type

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:

swift
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.

Accessibility Inspector: verificação do Dynamic Type

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

O que é Dynamic Type no iOS em termos simples?

É 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.

Dynamic Type funciona apenas com fontes do sistema?

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.

Quantos níveis de escala o iOS suporta?

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.

Como assinar as alterações de tamanho do texto?

No UIKit através de UIContentSizeCategory.didChangeNotification. No SwiftUI, use @Environment(\.dynamicTypeSize) — a visualização é atualizada automaticamente quando a configuração do sistema muda.

O que acontece se não houver suporte a Dynamic Type?

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

  • Dynamic Type — um mecanismo integrado do iOS para escalar texto conforme as configurações do sistema; obrigatório para a App Store
  • Use UIFont.preferredFont(forTextStyle:) para fontes do sistema e UIFontMetrics para personalizadas
  • O iOS suporta 11 níveis de escala — de XS a AccessibilityXXXXXL (14–53px para body)
  • No SwiftUI, o Dynamic Type funciona automaticamente via .font(.body) e @Environment(\.dynamicTypeSize)
  • O layout deve ser adaptativo: UIStackView, automaticDimension em tabelas, numberOfLines = 0
  • Teste todos os 11 níveis, especialmente as categorias de acessibilidade — 70% dos layouts quebram nelas
  • A assinatura de UIContentSizeCategory.didChangeNotification é obrigatória para aplicativos UIKit

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.

Discutir o projeto

Leia também