Tela de Inicialização e Ícones de Aplicativo no iOS para Flutter
Padrão testado em batalha para apps Flutter: logotipo de inicialização nativo no primeiro frame, mais ícones da tela inicial que seguem o Personalizar do iOS → Padrão / Escuro / Claro / Tintado.
Quando usar
- A inicialização a frio mostra uma tela branca/marfim antes do Flutter carregar
- Precisa de logotipos de inicialização claro + escuro que acompanham a aparência do sistema (não o ThemeCubit do app)
- Precisa de variantes de ícone do app Escuro / Tintado / Claro no iOS 18+
Quando não usar
- Splash Android / SplashScreen do Flutter in-app apenas
- Alternar tema in-app (HydratedBloc) — isso não controla a LaunchScreen nem os ícones da SpringBoard
Regras críticas (não pule)
- Logotipos de inicialização devem ser PNGs avulsos no bundle do app, não conjuntos de imagens do Catálogo de Ativos. O SplashBoard frequentemente falha ao usar
UIImage imageNameddo Assets.car no primeiro snapshot → tela em branco por 2–3s. - Não coloque BrandLogo em Assets.xcassets se o mesmo nome base existir como arquivo avulso — o catálogo vence e o carregamento falha.
- As cores de fundo na LaunchScreen devem ser sRGB explícitas no storyboard. Cores nomeadas (ex.
LaunchBackground) frequentemente falham ao alternar no snapshot de inicialização. - A chave de variação de trait é
userInterfaceStyle=dark(nãointerfaceStyle, nemluminosity=dark). - Nunca verifique a inicialização copiando um storyboardc
ibtoolavulso em um.appjá compilado — isso gera um flash preto. Sempre useflutter build ios --simulator(ou dispositivo) e depois desinstale + reinstale. - Não execute
flutter_launcher_iconsdepois de adicionar Escuro/Tintado — ele sobrescreve oContents.jsone remove as aparências. - O ícone da tela inicial segue a aparência do iPhone / Personalizar, não o tema Flutter. Claro é derivado de Tintado; não existe slot separado para Claro.
Checklist de workflow
Progresso:
- [ ] 1. Gerar PNGs de inicialização claro + noturno (@1x/@2x/@3x)
- [ ] 2. Copiar para ios/Runner/ e adicionar ao Copy Bundle Resources (pbxproj)
- [ ] 3. Remover qualquer BrandLogo*.imageset de Assets.xcassets
- [ ] 4. Atualizar LaunchScreen.storyboard (nomes de imagem avulsos + cores explícitas)
- [ ] 5. Opcional: LaunchBackground.colorset para Main.storyboard / SceneDelegate handoff apenas
- [ ] 6. Gerar ícone do app escuro + tintado 1024 (e tamanhos da tela inicial se mantendo entradas legadas)
- [ ] 7. Atualizar AppIcon.appiconset/Contents.json com luminosity dark + tinted
- [ ] 8. flutter build ios --simulator --debug
- [ ] 9. simctl uninstall + install; verificar inicialização <0,5s e aparências do ícone em Assets.car
Passo 1 — Gerar logotipos de inicialização
Use scripts/generate_launch_logos.py.
Entradas:
- Logotipo fonte com fundo de estúdio escuro (típico
assets/logo/logo.png) - Claro: preto recortado → cores da marca preservadas em dois tons
- Escuro: mesma máscara alfa, dourado sólido
#E0B45D(ou cor primária do projeto) - Tamanhos: 400×363 @1x, 800×727 @2x, 1200×1090 @3x (ajuste a proporção ao seu logotipo)
Fórmula de recorte (combinar com SplashLogo do Flutter se presente):
alpha_out = min(255, 4 * (R + G + B), source_alpha)
Arquivos de saída em ios/Runner/:
BrandLogo.png,[email protected],[email protected]BrandLogoNight.png,[email protected],[email protected]
Passo 2 — Recursos do bundle
Em ios/Runner.xcodeproj/project.pbxproj:
- Adicione
PBXFileReference+PBXBuildFilepara todos os seis PNGs - Liste-os no grupo Runner e em Copy Bundle Resources
lastKnownFileType = image.png; coloque os caminhos@2x/@3xentre aspas
Delete ios/Runner/Assets.xcassets/BrandLogo.imageset e BrandLogoNight.imageset se existirem.
Após a compilação, confirme:
# BrandLogo NÃO deve estar em Assets.car; os PNGs devem existir em Runner.app
find build/ios/iphonesimulator/Runner.app -name 'BrandLogo*.png'
xcrun assetutil --info build/ios/iphonesimulator/Runner.app/Assets.car | grep -i BrandLogo || true
Passo 3 — LaunchScreen.storyboard
Use formato IB moderno (toolsVersion ≥ 21701, useTraitCollections, capability "documents saved in the Xcode 8 format").
Padrão (modelo completo: references/launch-storyboard.md):
UIImageViewcontentMode="scaleAspectFit", imagemBrandLogo- Variação:
key="userInterfaceStyle=dark" image="BrandLogoNight" - Largura ≈ 0,28–0,40 da superview (comece ~0,32); altura = largura × proporção do logotipo
- Restrições de centro X/Y
- Fundo claro sRGB explícito (ex. marfim
#FFFCF7) - Variação de fundo escuro sRGB explícito (ex.
#17120E) <resources>deve declarar ambos os nomes de imagem com tamanhos intrínsecos
Info.plist: UILaunchStoryboardName = LaunchScreen.
Passo 4 — Handoff do Flutter (opcional, mas recomendado)
Evite flash branco quando o Flutter assumir:
LaunchBackground.colorsetcom luminosidade clara + escura (OK para UI não inicial)- Fundo do VC do Main.storyboard → nomeado
LaunchBackground - SceneDelegate /
FlutterViewControllerpersonalizado: definaview.backgroundColorewindow.backgroundColora partir deUIColor(named: "LaunchBackground")emviewDidLoad/viewDidLayoutSubviews
Passo 5 — Aparências do ícone do app (iOS 18+)
Gere com scripts/generate_app_icon_variants.py a partir do ícone de marketing 1024 (fundo creme + logotipo).
| Aparência | Arte |
|---|---|
| Padrão (Any) | Ícone claro existente |
| Escuro | Logotipo dourado sobre placa escura (#17120E) ou fundo transparente conforme HIG da Apple |
| Tintado | Escala de cinza: logotipo branco/cinza sobre preto (o sistema aplica a tinta) |
| Claro | Derivado automaticamente de Tintado — nenhuma entrada em Contents.json |
Atualize AppIcon.appiconset/Contents.json — veja references/appicon-contents.md.
Prefira entradas universais de Tamanho Único 1024 com:
"appearances": [{ "appearance": "luminosity", "value": "dark" }]
"appearances": [{ "appearance": "luminosity", "value": "tinted" }]
Mantenha entradas legadas por tamanho do iPhone se o projeto ainda as usar; adicione escuro/tintado para 60pt @2x/@3x + marketing 1024 no mínimo.
Valide:
xcrun actool ios/Runner/Assets.xcassets --compile /tmp/icons \
--platform iphonesimulator --minimum-deployment-target 15.0 \
--app-icon AppIcon --output-partial-info-plist /tmp/icon-partial.plist
xcrun assetutil --info /tmp/icons/Assets.car | grep -E 'UIAppearanceDark|ISAppearanceTintable'
O app compilado deve listar AppIcon com UIAppearanceDark e ISAppearanceTintable.
Passo 6 — Verificar no simulador
flutter build ios --simulator --debug
xcrun simctl uninstall booted <bundle.id>
xcrun simctl install booted build/ios/iphonesimulator/Runner.app
# Inicializar: esperar logotipo em ~0,4–0,5s (não tela em branco por vários segundos)
# Ícone: Personalizar → Escuro / Tintado; pode ser necessário deletar+reinstalar para cache da SpringBoard
simctl precisa de permissões completas em ambientes agent com sandbox.
Não rm -rf caches do SplashBoard; desinstalar + reinstalar limpa os snapshots de inicialização.
Padrões da marca (substituir por projeto)
| Token | Padrão |
|---|---|
| Fundo de inicialização claro | #FFFCF7 |
| Fundo de inicialização escuro | #17120E |
| Dourado do logotipo escuro | #E0B45D |
| Largura do logotipo de inicialização | 32% da tela |
| Placa do ícone escuro | #17120E |
Pergunte ao usuário os valores hex da marca quando o projeto diferir.
Recursos adicionais
- Modelo XML do storyboard: references/launch-storyboard.md
- Estruturas do Contents.json do AppIcon: references/appicon-contents.md
- Script de logotipo de inicialização: scripts/generate_launch_logos.py
- Script de variante de ícone: scripts/generate_app_icon_variants.py