Custom Font é um arquivo de fonte (TTF, OTF, WOFF2) que o desenvolvedor adiciona a um aplicativo móvel para substituir a fonte padrão do sistema. Fontes personalizadas são usadas para criar um estilo visual único, manter a consistência da marca e melhorar a legibilidade em diferentes idiomas. De acordo com Apple Fonts, as fontes personalizadas são compatíveis com todas as plataformas Apple, e o Android fornece o mecanismo Font Family para simplificar o carregamento. A integração adequada da fonte impacta criticamente a tipografia e a percepção geral do aplicativo.
Principais pontos
Custom Font (fonte personalizada) é um arquivo de tipo que não faz parte do conjunto de fontes padrão do sistema operacional. Os desenvolvedores adicionam essas fontes aos seus projetos para uma tipografia única e consistente com a marca. As fontes personalizadas podem ser tipos comerciais pagos ou fontes gratuitas de código aberto, como Inter, Montserrat ou uma versão personalizada do Roboto.
Os casos de uso típicos de fontes personalizadas incluem: logotipos e títulos de aplicativos de marca, aplicativos de leitura com requisitos tipográficos específicos, jogos com fontes temáticas e aplicativos para idiomas não latinos onde a fonte do sistema não oferece suporte aos glifos necessários. De acordo com Google Fonts, mais de 60% dos aplicativos no top 100 personalizam suas fontes para diferenciação visual.
As fontes do sistema (San Francisco no iOS, Roboto no Android) são otimizadas para interfaces, mas não são adequadas para tipografia de marca. Uma fonte personalizada fortalece o reconhecimento da marca, pode incluir caracteres especiais (fontes de ícones) e melhora a legibilidade para públicos específicos. No entanto, o uso excessivo de fontes diferentes degrada a experiência do usuário; recomenda-se não usar mais de 2–3 famílias por aplicativo.
As plataformas móveis suportam vários formatos de fonte. TrueType (TTF) é o formato mais comum, compatível com todas as versões do iOS e Android. OpenType (OTF) é uma extensão do TTF com suporte para ligaduras, glifos alternativos e recursos OpenType. Ambos os formatos têm extensões .ttf e .otf e funcionam de forma idêntica nas plataformas móveis.
WOFF2 (Web Open Font Format 2) é um formato compactado para a web, suportado no Android desde a versão 10. O WOFF2 fornece compressão de 30–50% em comparação com o TTF. Para iOS, o WOFF2 é suportado através do Safari, mas aplicativos nativos exigem conversão para TTF/OTF. As fontes variáveis (Variable Fonts) são um formato moderno que armazena todos os pesos em um único arquivo.
| Formato | iOS | Android | Compressão | Recursos |
|---|---|---|---|---|
| TTF | Sim | Sim | Não | Formato padrão, ampla compatibilidade |
| OTF | Sim | Sim | Não | Recursos OpenType, ligaduras, glifos alternativos |
| WOFF2 | Via Safari | API 29+ | 30–50% | Compactado, economiza espaço no APK |
| Variable | iOS 11+ | API 29+ | Alta | Arquivo único para todos os pesos |
Para desenvolvimento móvel, recomenda-se usar OTF como formato principal — ele suporta recursos OpenType com o mesmo tamanho do TTF. Para economizar espaço no APK, use compressão via woff2 ou carregamento de fontes sob demanda.
O processo de integração de uma fonte personalizada no iOS consiste em duas etapas: adicionar o arquivo ao bundle do projeto e registrá-lo no Info.plist. O arquivo de fonte é colocado no diretório do projeto (geralmente Resources/Fonts) e incluído no target. No Info.plist, é adicionado um array UIAppFonts (Fonts provided by application) com os nomes dos arquivos de fonte, incluindo a extensão.
Após o registro, a fonte fica acessível através de UIFont(name:size:) usando seu nome PostScript. O nome PostScript pode ser encontrado através de UIFont.familyNames e UIFont.fontNames(forFamilyName:). Se o nome estiver incorreto, UIFont(name:size:) retorna nil. Para depuração, recomenda-se exibir todas as fontes registradas na tela na primeira inicialização.
Vamos percorrer o ciclo completo de integração da fonte Montserrat em um projeto iOS em Swift. O arquivo Montserrat-Regular.ttf é adicionado ao projeto, declarado no Info.plist, depois carregado via UIFont e aplicado a um UILabel. Cada peso (regular, bold, italic) requer um arquivo separado e uma entrada separada no Info.plist.
// 1. No Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// 2. Carregar fonte no código
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
// recorrer à fonte do sistema
label.font = UIFont.systemFont(ofSize: 16)
return
}
label.font = customFont
// 3. Usar no NSAttributedString
let attributes = [NSAttributedString.Key.font: customFont]
let attributed = NSAttributedString(string: "Text", attributes: attributes)
Lidar com o caso em que a fonte não é carregada (UIFont retorna nil) é obrigatório. Em vez de travar o aplicativo, use a fonte do sistema como fallback. Isso é especialmente importante para fontes carregadas da rede ou adicionadas a módulos opcionais.
Para fontes baixadas sob demanda, usa-se CTFontManagerRegisterGraphicsFont. Este método registra uma fonte a partir de dados na memória (Data) e a disponibiliza para UIFont. Após o uso, a fonte pode ser cancelada via CTFontManagerUnregisterGraphicsFont. O carregamento dinâmico é útil para aplicativos com um grande conjunto de fontes onde nem todas são necessárias imediatamente.
No Android, as fontes personalizadas são adicionadas através do sistema de recursos res/font. Os arquivos TTF ou OTF são colocados em res/font/, após o que são criados recursos XML Font Family para agrupar os pesos. A partir do Android 8.0 (API 26), esta é a única forma recomendada. Para versões mais antigas, usam-se assets e Typeface.createFromAsset.
Um XML Font Family descreve o mapeamento entre um peso (regular, bold, italic) e um arquivo de fonte. No layout XML, o atributo android:fontFamily="@font/my_font" seleciona automaticamente o arquivo correto ao chamar setTypeface com o estilo correspondente. Isso simplifica a tipografia — basta especificar a família no tema e o Android escolherá a versão bold ao chamar setTypeface(textView, Typeface.BOLD).
Crie um arquivo XML em res/font/my_font.xml listando todos os arquivos de fonte para diferentes pesos. Cada elemento tem atributos fontStyle (normal/italic) e fontWeight (100–900). Em seguida, no layout, especifique android:fontFamily="@font/my_font". Quando textStyle="bold" é usado, o Android seleciona automaticamente o arquivo com fontWeight 700.
<!-- res/font/my_font.xml -->
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
<font
android:fontStyle="normal"
android:fontWeight="400"
app:font="@font/my_font_regular" />
<font
android:fontStyle="normal"
android:fontWeight="700"
app:font="@font/my_font_bold" />
</font-family>
Ao usar Font Family, a abordagem de recursos armazena em cache as fontes automaticamente e seleciona o peso correto. Se o peso necessário não estiver disponível na família, o Android o sintetiza a partir do mais próximo disponível. Para controle preciso sobre a fonte, use Typeface.create() com uma referência explícita ao arquivo.
Em frameworks multiplataforma, a integração de fontes é unificada. Flutter usa pubspec.yaml para declarar fontes: os arquivos são colocados na pasta fonts/ do projeto e depois listados na seção fonts com a família e os pesos. A fonte é então aplicada via TextStyle(fontFamily: 'Montserrat') ou no tema do aplicativo. Flutter suporta TTF e OTF.
React Native usa duas abordagens: nativa (via Info.plist e res/font) ou através de bibliotecas como react-native-vector-icons e @expo-google-fonts. O Expo simplifica o processo — as fontes são carregadas via expo-font: Font.loadAsync({ 'Montserrat': require('./assets/fonts/Montserrat.ttf') }). O React Navigation e os temas permitem definir uma fonte globalmente.
Declaração de fontes no pubspec.yaml e aplicação no tema do MaterialApp. Os arquivos Montserrat-Regular.ttf e Montserrat-Bold.ttf são colocados em fonts/. Após a declaração, a fonte fica acessível via TextStyle em todo o aplicativo. O Flutter usa automaticamente o arquivo bold quando fontWeight: FontWeight.bold é especificado.
// pubspec.yaml
flutter:
fonts:
- family: Montserrat
fonts:
- asset: fonts/Montserrat-Regular.ttf
- asset: fonts/Montserrat-Bold.ttf
weight: 700
// Uso no tema
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
headlineLarge: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
fontSize: 28
)
)
)
)
Se o Flutter não encontrar uma fonte no caminho especificado, o aplicativo usa a fonte de fallback do sistema sem erros. Para depuração, ative checkConsistency no MaterialApp — ele verifica a disponibilidade das fontes e imprime avisos no console quando as fontes estão faltando.
O tamanho do APK e do IPA depende diretamente do número de fontes incluídas. Um único arquivo TTF pesa 50–500 KB para o conjunto de caracteres latinos e até 2–5 MB para fontes que suportam cirílico, caracteres CJK ou outros conjuntos estendidos. Dez fontes podem adicionar 10–20 MB ao tamanho do aplicativo, o que é crítico para downloads móveis.
Para otimização, use subsetting — remoção de caracteres não utilizados do arquivo de fonte. Ferramentas como glyphhanger, fonttools (pyftsubset) e Google Webfont Optimizer criam uma versão da fonte apenas com os glifos necessários (latim + cirílico + dígitos + pontuação). Isso reduz o tamanho em 50–80%. No iOS, recursos sob demanda podem ser usados para fontes que não são necessárias na primeira inicialização.
Uma fonte variável (Variable Font) é um único arquivo contendo todos os pesos, de Thin a Black e de Condensed a Expanded. Uma fonte variável pode substituir 10–20 arquivos separados com pesos diferentes. O tamanho desse arquivo é aproximadamente igual a 1–2 arquivos estáticos. Suporte: iOS 11+, Android 10+, Flutter (via FontVariation), React Native (via bibliotecas personalizadas).
Use WOFF2 para reduzir o tamanho das fontes em 30–50%. No Android com API 29, o WOFF2 pode ser usado diretamente. Para iOS, é necessário converter WOFF2 para TTF antes do registro. Fontes usadas apenas durante a integração ou em telas específicas devem ser carregadas via recursos sob demanda (iOS) ou Dynamic Feature (Android) — elas não serão incluídas no APK base.
As fontes personalizadas afetam o desempenho de duas maneiras: tempo de carregamento e memória. No primeiro acesso, o sistema lê o arquivo do disco, analisa as tabelas da fonte e cria estruturas internas para renderização. Para uma fonte de 1 MB, isso leva de 20 a 50 ms. O armazenamento em cache após o primeiro carregamento elimina o atraso em acessos subsequentes.
Memória: cada fonte carregada é armazenada no cache do processo. As fontes do sistema são pré-carregadas; as fontes personalizadas são carregadas no primeiro uso. Na memória, uma fonte ocupa aproximadamente 2–3 vezes mais espaço do que no disco devido às estruturas analisadas: tabelas cmap, glyf, head, hmtx. Para 5 fontes personalizadas de tamanho médio (3 MB no total), são necessários cerca de 6–9 MB de RAM.
Limite as fontes personalizadas a 2–3 famílias por aplicativo. Use fontes variáveis para substituir vários pesos. Aplique fontes do sistema para elementos de interface (botões, rótulos, listas) e fontes personalizadas apenas para tipografia de destaque (títulos, banners). Armazene em cache Typeface no Android através de um Map e UIFont no iOS através de variáveis estáticas.
object FontCache {
private val cache = mutableMapOf<String, Typeface>()
fun get(context: Context, fontId: Int): Typeface {
return cache.getOrPut(fontId.toString()) {
ResourcesCompat.getFont(context, fontId)
}
}
}
// Uso no RecyclerView
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.typeface = FontCache.get(context, R.font.montserrat_regular)
}
Carregar Typeface em onBindViewHolder só é aceitável com cache. Sem cache, cada chamada createFromAsset cria um novo objeto e lê o arquivo do disco. Durante a rolagem do RecyclerView, isso causa lentidão perceptível. O cache resolve o problema porque a fonte é carregada uma vez e reutilizada.
Perguntas frequentes
OTF é a melhor escolha para aplicativos móveis. Ele suporta recursos OpenType (ligaduras, glifos alternativos) com o mesmo tamanho do TTF. Para economizar espaço, use fontes variáveis (TTX ou OTF) com subsetting. O WOFF2 é adequado apenas para Android 10+ e não é suportado no iOS em aplicativos nativos.
Sim. O Google Fonts fornece fontes sob licença OFL (Open Font License) para uso comercial. As fontes podem ser baixadas de fonts.google.com e adicionadas ao projeto. O Android suporta Downloadable Fonts através do Google Play Services, permitindo não incluir arquivos de fonte no APK e carregá-los no primeiro uso.
As razões mais comuns: o arquivo não foi adicionado ao target (iOS), não foi declarado no Info.plist (iOS), o arquivo não está em res/font (Android), o nome PostScript está incorreto ou o arquivo está corrompido. Para diagnóstico no iOS, imprima UIFont.familyNames no console. No Android, use FontLoader para depurar o carregamento de fontes de assets.
Use subsetting (pyftsubset) para remover caracteres não utilizados — reduz o tamanho em 50–80%. Use fontes variáveis em vez de 10 arquivos separados. Use compressão WOFF2 para Android 10+. Configure o ProGuard para ofuscar os caminhos das fontes. Para iOS, use recursos sob demanda.
Recomenda-se limitar a 2–3 famílias (incluindo pesos diferentes). Cada família adiciona 200 KB a 3 MB ao tamanho do aplicativo. As fontes do sistema não sobrecarregam o aplicativo, portanto, use fontes do sistema para elementos de interface e reserve as personalizadas para títulos e blocos de destaque.
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