Design para Dispositivos Móveis — Habilidade Completa
Visão Geral
Abrange design para iOS e Android: padrões específicos de cada plataforma, navegação, gestos, tipografia, acessibilidade e tendências modernas. Unifica building-native-ui, expo-ui-swiftui, expo-ui-jetpack-compose, engineering-mobile-app-builder, react-native-best-practices, expo-tailwind-setup e native-data-fetching.
1. Diretrizes da Plataforma
1.1 iOS (Human Interface Guidelines)
- Navegação: push/pop (UINavigationController), barra de abas, folhas modais
- Tipografia: SF Pro (San Francisco) — New York (serif) para leitura
- Grade: grade de 4pt, margens: 16pt (padrão), 20pt (grande)
- Cores: cores do sistema (azul, verde, vermelho, laranja, roxo, rosa, ciano, índigo, cinza)
- Alvos de toque: mínimo 44×44pt
- Gesto de voltar: deslizar da borda esquerda
- Áreas seguras: notch, indicador de início (usar
safe-area-inset)
- Modo escuro: adaptação do sistema
UIColor { traitCollection }
1.2 Android (Material Design 3)
- Navegação: navegação inferior, gaveta de navegação, barra de aplicativo superior, botão voltar
- Tipografia: Roboto (sistema), Google Sans (marca)
- Grade: grade de 4dp, margens: 16dp
- Cores: cor dinâmica (Material You), paletas tonais
- Alvos de toque: mínimo 48×48dp
- Botão voltar: voltar do sistema (volta preditiva no Android 14)
- Elevação: sombras representam profundidade e prioridade de interação
- Efeito ripple: feedback de toque em todos os elementos interativos
1.3 Cross-Platform (React Native / Expo)
- Tente o Expo Go primeiro para prototipagem rápida
- Use
useWindowDimensions() em vez de Dimensions.get()
boxShadow para sombras cross-platform (não shadow/elevation legadas)
expo-image para melhor carregamento de imagens e símbolos SF
- Código específico da plataforma:
.ios.tsx / .android.tsx
2. Navegação Móvel
2.1 Padrões de Navegação
| Padrão | Quando Usar | Plataforma |
|---|
| Barra de Abas | 3-5 destinos de nível superior | iOS (inferior), Android (inferior) |
| Navegação Inferior | 3-5 destinos de nível superior | Material Design |
| Gaveta de Navegação | Muitos destinos, acesso pouco frequente | Android |
| Navegação em Pilha | Detalhamento hierárquico | Ambas |
| Folhas Modais | Tarefas focadas, ações rápidas | iOS (form sheet), Android (bottom sheet) |
| Modal em Tela Cheia | Fluxos de várias etapas | Ambas |
| Ações de Deslizar | Ações em itens de lista (excluir, arquivar) | Ambas |
2.2 Regras da Barra de Abas
- Máximo de 5 abas (iOS), 5 no máximo (Material)
- Estado ativo: ícone preenchido + mudança de cor do rótulo
- Emblema: ponto vermelho com contagem para notificações
- Área segura: acima do indicador de início no iOS
2.3 Navegação em Pilha
- Push: deslizar da direita (iOS), fade+slide (Android)
- Pop: deslizar da borda esquerda (iOS), botão voltar (Android)
- Transição: 300ms (iOS), 200-300ms (Android)
2.4 Gestos
- Deslizar: ações de lista, navegação entre telas
- Puxar para atualizar: padrão comum para listas
- Pressionar e segurar: menu contextual (atraso de 300-500ms)
- Pinça para ampliar: imagens, mapas
- Toque duplo: ampliar, curtir (aplicativos sociais)
3. Tipografia Móvel
3.1 Escala Tipográfica
| Estilo | Tamanho | Peso | Altura da Linha |
|---|
| Título Grande | 34pt | 700 | 41pt |
| Título 1 | 28pt | 700 | 34pt |
| Título 2 | 22pt | 700 | 28pt |
| Título 3 | 20pt | 600 | 25pt |
| Manchete | 17pt | 600 | 22pt |
| Corpo | 17pt | 400 | 22pt |
| Destaque | 16pt | 400 | 21pt |
| Subtítulo | 15pt | 400 | 20pt |
| Nota de Rodapé | 13pt | 400 | 18pt |
| Legenda 1 | 12pt | 400 | 16pt |
| Legenda 2 | 11pt | 400 | 13pt |
3.2 Regras
- Tamanho mínimo do texto: 12sp (Android), 11pt (iOS)
- Texto do corpo: 16-17pt para leitura confortável
- Altura da linha: 1.3-1.5× o tamanho da fonte
- Nunca truncar: texto crítico (números, nomes, datas)
- Comprimento da linha: máximo de 40-70 caracteres
- Tipo dinâmico: suportar tamanho do texto do sistema (iOS:
UIFontMetrics, Android: sp)
4. Componentes Móveis
4.1 Componentes Comuns
| Componente | iOS | Android (Material) |
|---|
| Botão | UIButton (preenchido, matizado, cinza) | Elevado, preenchido, tonal, delineado, texto |
| Lista | UITableView (agrupada, inserida) | RecyclerView (lista, cartão) |
| Entrada | UITextField | TextField (preenchido, delineado) |
| Alternar | UISwitch | Switch |
| Controle Deslizante | UISlider | Slider |
| Seletor | Seletor de roda / dropdown | Menu dropdown |
| Barra de abas | UITabBar | BottomNavigationView |
| Pesquisa | UISearchBar | SearchBar |
| Toast | N/A (usar personalizado) | Snackbar |
4.2 Padrões de Lista
- Padrão: ícone + título + subtítulo + chevron
- Ação: deslizar para a esquerda → excluir/arquivar/compartilhar
- Agrupada: cabeçalhos de seção com itens agrupados
- Cartão: imagem + título + descrição + ações
- Rolagem infinita: carregar mais ao rolar (com indicador de carregamento)
4.3 Padrões de Formulário
- Coluna única sempre (dispositivo móvel)
- Rótulos: acima das entradas (não apenas flutuantes)
- Tipo de teclado: corresponder à entrada (numérico, e-mail, telefone)
- Evitar teclado: rolar formulário quando o teclado aparecer
- Validação: inline abaixo do campo, mudança de cor
- Enviar: botão inferior fixo ou ação do formulário
5. Layout Móvel
5.1 Áreas Seguras
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
<View style={{ paddingTop: insets.top, paddingBottom: insets.bottom }} />
5.2 Densidade de Tela
- iPhone SE: 375×667pt (menor)
- iPhone 14: 390×844pt
- iPhone 14 Pro Max: 430×932pt
- Android: 360×640dp (comum), varia amplamente
5.3 Alvos de Toque
- Mínimo: 44×44pt (iOS), 48×48dp (Android)
- Preferido: 48×48pt para zonas amigáveis ao polegar
- Espaçamento: mínimo de 8pt entre alvos de toque adjacentes
5.4 Zonas do Polegar
- Melhor zona: metade inferior da tela (alcance natural do polegar)
- Ações primárias: terço inferior (especialmente em telefones grandes)
- Ações destrutivas: longe da zona primária
6. Sistema de Design Móvel
6.1 Sistema de Cores
--primary: #007AFF;
--background: #FFFFFF;
--surface: #F2F2F7;
--text-primary: #000000;
--text-secondary: #8E8E93;
--separator: #C6C6C8;
--success: #34C759;
--error: #FF3B30;
--warning: #FF9500;
--primary: #0A84FF;
--background: #000000;
--surface: #1C1C1E;
--text-primary: #FFFFFF;
--text-secondary: #8E8E93;
6.2 Modo Escuro
- Alternância em todo o sistema (seguir configuração do SO)
- Preto puro (#000) para OLED (iOS) ou cinza escuro (#121212) para Android
- Reduzir ligeiramente o contraste no modo escuro
- Testar ambos os modos para cada tela
6.3 Iconografia
- iOS: SF Symbols (sistema), ícones personalizados (específicos do aplicativo)
- Android: Material Icons (sistema), personalizados
- Tamanho: 24×24dp padrão, 18×18dp pequeno, 28×28dp grande
- Estilo: preenchido (ativo), delineado (inativo)
7. Movimento e Animação
7.1 Princípios
- Duração: 250-350ms (padrão), 150-200ms (rápido), 500ms ou mais (complexo)
- Easing:
cubic-bezier(0.2, 0, 0, 1) (Material), ease-out (iOS)
- Propósito: indicar navegação, confirmar ação, mostrar carregamento, encantar
7.2 Padrões Comuns
| Animação | Duração | Uso |
|---|
| Push/pop de página | 300ms | Navegação em pilha |
| Apresentar/descartar modal | 300ms | Folhas modais |
| Fade in | 200ms | Carregamento de conteúdo |
| Deslizar para cima | 250ms | Bottom sheet |
| Escalar | 200ms | Feedback de pressionar botão |
| Esqueleto | Loop de 1.5s | Carregamento de conteúdo |
| Puxar para atualizar | 200ms | Atualização de lista |
7.3 Específicos da Plataforma
- iOS: física de mola (natural, elástico)
- Android: easing padrão (previsível, suave)
- Hápticos: impacto leve (pressionar botão), médio (seleção), padrões de sucesso/erro
8. Padrões de UX Móvel
8.1 Integração
- Máximo de 3-5 telas: proposta de valor → funcionalidades → permissões → CTA
- Opção de pular: sempre disponível
- Indicador de progresso: pontos ou barra de progresso
- Solicitações de permissão: explicar o PORQUÊ antes de solicitar
8.2 Estados Vazios
- Ilustração ou ícone
- Mensagem clara
- Botão de call-to-action
- Exemplos: "Nenhum resultado", "Seu carrinho está vazio", "Sem notificações"
8.3 Estados de Carregamento
- Telas esqueleto (preferidas em vez de spinners)
- Barras de progresso para operações mensuráveis
- Puxar para atualizar para listas
- UI otimista para ações (atualizar imediatamente, reverter em caso de erro)
8.4 Estados de Erro
- Inline: erros de validação em nível de campo
- Tela cheia: erros críticos com botão de repetir
- Toast/snackbar: erros transitórios (3-5 segundos)
- Offline: conteúdo em cache + banner "Você está offline"
8.5 Notificações
- Push: solicitação de permissão com explicação
- No aplicativo: emblema, banner ou caixa de entrada
- Configurações: controle granular (por categoria)
9. Acessibilidade
9.1 Lista de Verificação
9.2 Leitor de Tela
- VoiceOver iOS:
accessibilityLabel, accessibilityHint, accessibilityTraits
- TalkBack Android:
contentDescription, accessibilityRole
- Teste: ativar o leitor de tela e navegar pelo aplicativo completo
10. Performance
10.1 Métricas Principais
- TTI (Time to Interactive): < 2s
- Taxa de quadros: 60 FPS (16.67ms por quadro)
- Tamanho do aplicativo: minimizar pacote
- Memória: sem vazamentos, limpeza adequada
10.2 Otimização
- Usar
FlatList (não ScrollView) para listas longas
- Memorizar componentes caros (
React.memo, useMemo, useCallback)
- Carregar telas e imagens sob demanda
- Reduzir re-renderizações (
key prop corretas, evitar funções anônimas em props)
- Cache de imagens e compressão
- Motor Hermes para React Native
11. Componentes de UI Nativos do Expo
11.1 Expo UI — SwiftUI (iOS)
npx expo install @expo/ui
import { Host, SwiftUIButton } from '@expo/ui/swift-ui';
export default function Screen() {
return (
<Host> {/* toda árvore SwiftUI precisa de Host */}
<SwiftUIButton title="Tap me" action={onPress} />
</Host>
);
}
- ⚠️ Toda árvore SwiftUI deve ser envolvida em
Host — caso contrário, nada é renderizado
- Embutir componentes React Native dentro de uma árvore SwiftUI com
RNHostView
- Leia o
.d.ts do pacote e a documentação do componente antes de usar — modificadores mudam entre versões do SDK
11.2 Expo UI — Jetpack Compose (Android)
import { Host, Button } from '@expo/ui/jetpack-compose';
import { composeModifiers } from '@expo/ui/jetpack-compose/modifiers';
<Host>
<Button title="Tap me" modifiers={[composeModifiers.padding(16)]} onPress={onPress} />
</Host>
- ⚠️ Envolva toda árvore Compose em
Host (mesma regra do SwiftUI)
- Listas longas →
LazyColumn; ícones → Icon com arquivos XML locais
- Leia o
.d.ts do componente antes de usar modificadores — a API é específica da versão do SDK
11.3 NativeWind v5 + Tailwind v4 (estilização cross-platform)
npm i nativewind react-native-css tailwindcss @tailwindcss/postcss
import { styled } from 'nativewind';
export const View = styled(NativeView);
- Nenhuma alteração em
babel.config.js necessária — react-native-css lida com a transformação em tempo de execução
- A saída está em
src/tw/ (componentes encapsulados View, Text, Image, animated)
- Use
className em todos os lugares; recorra a style para casos pontuais
- Alvo web: o mesmo
className funciona no React Native Web — uma base de código, três plataformas
11.4 Quando Usar Cada Um
| Necessidade | Use |
|---|
| Aparência nativa (SwiftUI/Compose) | @expo/ui com Host |
| Cross-platform + iteração rápida | NativeWind v5 |
| Desenho / animação personalizados | Reanimated + Skia |
| Componentes RN padrão | Componentes internos View/Text/Pressable |
12. Lista de Verificação
Habilidades Relacionadas
$design-web — para design de interface web
$design-desktop — para design de aplicativo desktop
$design-figma — para trabalho de design no Figma
$mobile-development — para desenvolvimento Expo/React Native
$testing-comprehensive — para testar aplicativos móveis e desktop