UIFont e CTFont são classes para trabalhar com fontes no iOS: UIFont do UIKit para configuração de texto de alto nível em UILabel e UITextView, CTFont do Core Text para renderização de baixo nível com controle total sobre glifos e métricas. De acordo com Apple Developer Documentation, UIFont é usado em 90% dos componentes de UI padrão, enquanto CTFont é usado em motores de texto personalizados e editores. Ambas as classes representam uma mesma fonte, mas com diferentes níveis de abstração.
Principais conclusões
UIFont é uma classe UIKit que representa uma fonte para exibir texto em componentes de UI: UILabel, UITextView, UITextField. Ela fornece uma interface simples para obter fontes do sistema e personalizadas com tamanho, peso e estilo especificados. UIFont não permite controle direto sobre kerning, ligaduras e recursos OpenType — para isso, usa-se Core Text.
CTFont é um tipo Core Text (CTFontRef) que fornece acesso de baixo nível aos dados da fonte. CTFont trabalha diretamente com Core Graphics para renderização, suporta todos os recursos OpenType e TrueType, incluindo glifos alternativos, ligaduras e fontes variáveis. CTFont é usado internamente pelo UIKit para renderizar UIFont, mas também está disponível diretamente para desenho personalizado.
UIFont e CTFont suportam toll-free bridging — conversão entre tipos sem custo adicional. O casting UIFont as CTFont ou CTFont as UIFont é possível em Swift e Objective-C. Isso permite usar a API de alto nível do UIKit para configuração e o Core Text de baixo nível para renderização sem copiar dados da fonte.
Ambas as classes usam UIFontDescriptor (UIKit) / CTFontDescriptor (Core Text) para descrever características da fonte: nome, tamanho, peso, estilo, matriz de transformação. Um descritor é um dicionário de atributos que pode ser modificado para criar novas fontes baseadas em existentes. Por exemplo, adicionar traitItalic a um descritor e obter uma versão itálica da mesma fonte.
UIFont fornece vários métodos de fábrica para criar fontes. systemFont(ofSize:) retorna a fonte do sistema San Francisco (iOS) ou Helvetica (versões antigas). boldSystemFont, italicSystemFont — variantes com estilos específicos. preferredFont(forTextStyle:) retorna uma fonte Dynamic Type para o estilo dado: .headline, .body, .caption1, .footnote. Essas fontes são dimensionadas automaticamente quando as configurações de tamanho de texto mudam no sistema.
Para carregar fontes personalizadas, usa-se UIFont(name:size:) com o nome PostScript da fonte. A fonte deve ser primeiro adicionada ao Info.plist e incluída no bundle do aplicativo. De acordo com a Apple, recomenda-se usar UIFont para todos os componentes de UI padrão e mudar para CTFont apenas quando for necessário renderização personalizada.
Dynamic Type é um sistema de fontes adaptativo introduzido no iOS 7. O usuário seleciona o tamanho de texto preferido nas Configurações — de extra pequeno a extra grande. UIFont.preferredFont retorna automaticamente uma fonte do tamanho apropriado. Para funcionamento correto, todos os UILabel devem ter adjustsFontForContentSizeCategory = true. Dynamic Type é obrigatório para conformidade de acessibilidade.
UIFontDescriptor permite modificar atributos de fonte sem criar uma nova instância do zero. Os métodos addingAttributes(_:), withSymbolicTraits(_:), withFamily(_:) retornam um novo descritor com parâmetros alterados. Isso é conveniente para obter variantes de fonte: adicionar traitBold à fonte do sistema e obter uma versão em negrito sem saber o nome PostScript.
CTFont (CTFontRef) é um tipo Core Text para trabalho de baixo nível com fontes. É criado por CTFontCreateWithName, CTFontCreateWithFontDescriptor, CTFontCreateCopyWithAttributes. Cada função retorna uma fonte com a interface, tamanho e atributos opcionais especificados. CTFont é usado no Core Graphics para renderizar texto em UIView personalizado via drawRect.
CTFont fornece acesso a métricas não disponíveis no UIFont: CTFontGetGlyphsForCharacters retorna um array de glifos para caracteres dados, CTFontGetAdvancesForGlyphs — a largura de cada glifo, CTFontGetBoundingBox — os limites do glifo. Isso é necessário para construir layouts de texto personalizados: colunas, rotação, ajuste.
CTFontGetAscent, CTFontGetDescent, CTFontGetLeading retornam métricas verticais de fonte. CTFontGetUnitsPerEm — número de unidades por em-quadrado, usado para cálculo de proporções. CTFontGetGlyphCount — número total de glifos na fonte. Esses dados são críticos para tipografia de impressão e layouts personalizados onde é necessário posicionamento preciso de cada caractere.
CTFont suporta recursos OpenType: CTFontCopyFeatures retorna um dicionário de funções disponíveis da fonte (ligaduras, caracteres alternativos, kerning), CTFontEnableFeature ativa uma opção específica. Fontes variáveis são configuradas via CTFontCopyVariation e CTFontCreateCopyWithVariation, permitindo alterar weight, width e slant em um intervalo contínuo.
A criação de UIFont em Swift é feita através de um dos métodos de fábrica ou inicialização direta por nome. A forma mais comum é systemFont(ofSize:weight:) para fontes do sistema ou preferredFont(forTextStyle:) para Dynamic Type. Para fontes personalizadas, usa-se UIFont(name:size:) com o nome PostScript especificado.
UIFont.systemFont(ofSize:weight:) aceita UIFont.Weight — de .ultraLight a .black. Este método retorna a fonte do sistema San Francisco com o peso correspondente. UIFont.monospacedSystemFont, UIFont.monospacedDigitSystemFont retornam fontes monoespaçadas para código e números. Todas as fontes do sistema suportam automaticamente Dynamic Type.
let regularFont = UIFont.systemFont(ofSize: 16, weight: .regular)
let boldFont = UIFont.systemFont(ofSize: 16, weight: .bold)
let headlineFont = UIFont.preferredFont(forTextStyle: .headline)
let monoFont = UIFont.monospacedSystemFont(ofSize: 14, weight: .regular)
label.font = headlineFont
Cada fonte pode ser atribuída diretamente à propriedade font de UILabel ou usada em NSAttributedString via NSFontAttributeName. As fontes do sistema são armazenadas em cache pelo iOS, portanto recriar uma fonte do sistema não gera sobrecarga.
Para usar uma fonte personalizada, adicione o arquivo TTF ou OTF ao bundle do projeto e especifique-o em Info.plist (UIAppFonts). O nome PostScript da fonte pode ser encontrado via UIFont.familyNames e UIFont.fontNames(forFamilyName:). Após o registro, a fonte está disponível via UIFont(name:size:) de qualquer lugar do aplicativo.
// Obter todos os nomes de famílias de fontes
for family in UIFont.familyNames {
let names = UIFont.fontNames(forFamilyName: family)
print("\(family): \(names)")
}
// Carregar fonte personalizada
if let customFont = UIFont(name: "MyCustomFont-Regular", size: 18) {
label.font = customFont
}
Se o nome da fonte for especificado incorretamente, UIFont(name:size:) retorna nil. Recomenda-se imprimir todos os nomes de fonte disponíveis via UIFont.familyNames e UIFont.fontNames(forFamilyName:) durante a depuração para garantir que a fonte esteja registrada corretamente.
O carregamento de fontes personalizadas é possível de duas maneiras: registro estático via Info.plist (UIAppFonts) e registro dinâmico via CTFontManagerRegisterGraphicsFont. O primeiro método é mais simples — a fonte está disponível imediatamente após a inicialização do aplicativo. O segundo é usado para fontes baixadas da rede ou recursos sob demanda.
O registro dinâmico é útil para recursos sob demanda: se o aplicativo contém mais de 20 fontes, todas podem ser excluídas do bundle inicial e baixadas no primeiro uso. CTFontManagerRegisterFontsForURLs registra fontes de URLs especificadas. Após o registro, a fonte fica disponível via UIFont(name:size:) normalmente.
Para renderização personalizada via Core Text, use CTFontCreateWithName com o nome PostScript da fonte. A diferença com UIFont é que CTFont pode ser criado com uma matriz de transformação (CTFontCreateWithNameAndOptions) — para criar fontes distorcidas: inclinação, escala no eixo X, rotação. Isso não está disponível em UIFont sem usar transformações afins.
// Criar CTFont com matriz de distorção
var matrix = CGAffineTransform(a: 1, b: 0, c: 0.2, d: 1, tx: 0, ty: 0)
let ctFont = CTFontCreateWithName(
"Helvetica" as CFString,
24, &matrix)
// Usar toll-free bridging com UIFont
let uiFont = ctFont as UIFont
label.font = uiFont
A matriz de transformação permite criar variantes itálicas sem um arquivo de fonte separado. O parâmetro c (skew) adiciona inclinação aos caracteres. A matriz também permite escalar a fonte horizontalmente — criando variantes condensadas ou expandidas de uma mesma fonte.
A principal diferença entre UIFont e CTFont é o nível de abstração. UIFont fornece uma API simples para tarefas comuns: obter uma fonte do sistema, alterar tamanho, aplicar a UILabel. CTFont fornece controle total sobre a fonte: acesso a glifos, métricas, tabelas OpenType e eixos variáveis. A escolha depende da tarefa.
| Característica | UIFont | CTFont |
|---|---|---|
| Framework | UIKit | Core Text |
| Criação | systemFont / preferredFont / initWithName | CTFontCreateWithName / CTFontCreateWithDescriptor |
| Acesso a glifos | Não | CTFontGetGlyphsForCharacters |
| Recursos OpenType | Limitado (UIFontDescriptor) | Acesso completo |
| Fontes variáveis | Via UIFontDescriptor | CTFontCopyVariation / CreateCopyWithVariation |
| Renderização | Automática em componentes de UI | Core Graphics, personalizada |
Para 95% das tarefas de desenvolvimento iOS, UIFont é suficiente. Core Text com CTFont se justifica ao criar editores de texto, geradores de PDF, livros com layout tipográfico ou aplicativos com renderização personalizada de idiomas raros.
Trabalhar com fontes no iOS requer consideração de desempenho. Cada fonte única é carregada na memória no primeiro acesso e consome recursos. As fontes do sistema San Francisco são pré-carregadas e não geram sobrecarga. Fontes personalizadas são carregadas de arquivo e armazenadas em cache pelo sistema após o primeiro carregamento.
Recomenda-se limitar o número de fontes únicas em um aplicativo a 3-5 famílias. Cada fonte ocupa de 50 KB a 2 MB na memória. Usar diferentes pesos de uma mesma família (regular, bold, medium) é mais eficiente do que carregar várias famílias diferentes.
O sistema armazena em cache as instâncias criadas de UIFont, portanto chamadas repetidas a UIFont.systemFont(ofSize: 16, weight: .regular) não criam um novo objeto. No entanto, UIFont(name:size:) para fontes personalizadas nem sempre é armazenado em cache — recomenda-se salvar fontes usadas com frequência em propriedades estáticas ou NSCache para evitar recarregar do arquivo.
Ao registrar fontes dinamicamente via CTFontManagerRegisterGraphicsFont, o processo pode ser assíncrono se o arquivo de fonte for baixado da rede. Nesse caso, UILabel ou UITextView devem exibir uma fonte do sistema de fallback até que o carregamento seja concluído. Após o registro, a fonte fica disponível e a tela atualiza automaticamente a exibição do texto.
Perguntas frequentes
Sim, UIFont e CTFont suportam toll-free bridging. A conversão é feita por casting simples: UIFont as CTFont ou CTFont as UIFont. Não ocorre sobrecarga ou cópia de dados — ambas as classes apontam para o mesmo objeto de fonte na memória.
Para todos os componentes de UI, use UIFont. Ele é otimizado para UIKit, suporta Dynamic Type e escala corretamente quando as configurações do sistema mudam. CTFont só se justifica para renderização personalizada via Core Graphics ou quando é necessário acesso a métricas de fonte de baixo nível.
Use UIFont.familyNames para uma lista de famílias e UIFont.fontNames(forFamilyName:) para nomes PostScript. Execute este código em modo debug e encontre a fonte desejada. O nome PostScript normalmente contém o nome da família e o estilo: “SFProText-Regular”, “HelveticaNeue-Bold”.
Sim, através de UIFontDescriptor você pode configurar eixos variáveis: weight, width, slant. No entanto, a API UIFont para fontes variáveis é limitada em comparação com CTFontCopyVariation. Para controle total sobre eixos variáveis, use Core Text e CTFontCreateCopyWithVariation.
Crie um dicionário estático ou NSCache com uma chave combinando nome e tamanho. Para fontes do sistema, o iOS armazena instâncias em cache automaticamente, mas para fontes personalizadas criadas via UIFont(name:size:), recomenda-se salvar objetos no cache do aplicativo para evitar recarregar do arquivo TTF.
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