O que Sistema de Design Liquid Glass (iOS 26) faz?
Padrões para implementar o Liquid Glass da Apple — um material dinâmico que desfoca o conteúdo por trás dele, reflete cores e iluminação do conteúdo ao redor e reage a interações de toque e ponteiro. Abrange integração com SwiftUI, UIKit e WidgetKit.
Quando Ativar
- Ao construir ou atualizar apps para iOS 26+ com a nova linguagem de design
- Ao implementar botões, cartões, barras de ferramentas ou contêineres no estilo vidro
- Ao criar transições de morphing entre elementos de vidro
- Ao aplicar efeitos Liquid Glass a widgets
- Ao migrar efeitos de desfoque/material existentes para a nova API Liquid Glass
Padrão Principal — SwiftUI
Efeito de Vidro Básico
A maneira mais simples de adicionar Liquid Glass a qualquer vista:
Text("Olá, Mundo!")
.font(.title)
.padding()
.glassEffect() // Padrão: variante regular, forma de cápsula
Personalizando Forma e Matiz
Text("Olá, Mundo!")
.font(.title)
.padding()
.glassEffect(.regular.tint(.laranja).interactive(), in: .rect(cornerRadius: 16.0))
Opções principais de personalização:
.regular— efeito de vidro padrão.tint(Cor)— adiciona matiz de cor para destaque.interactive()— reage a interações de toque e ponteiro- Forma:
.capsule(padrão),.rect(cornerRadius:),.circle
Estilos de Botão de Vidro
Button("Clique em Mim") { /* ação */ }
.buttonStyle(.glass)
Button("Importante") { /* ação */ }
.buttonStyle(.glassProminent)
GlassEffectContainer para Múltiplos Elementos
Sempre envolva várias vistas de vidro em um contêiner para desempenho e morphing:
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.font(.system(size: 36))
.glassEffect()
}
}
O parâmetro spacing controla a distância de mesclagem — elementos mais próximos misturam suas formas de vidro.
Unindo Efeitos de Vidro
Combine várias vistas em uma única forma de vidro com glassEffectUnion:
@Namespace private var namespace
GlassEffectContainer(spacing: 20.0) {
HStack(spacing: 20.0) {
ForEach(symbolSet.indices, id: \.self) { item in
Image(systemName: symbolSet[item])
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectUnion(id: item < 2 ? "grupo1" : "grupo2", namespace: namespace)
}
}
}
Transições de Morphing
Crie morphing suave quando elementos de vidro aparecem/desaparecem:
@State private var isExpanded = false
@Namespace private var namespace
GlassEffectContainer(spacing: 40.0) {
HStack(spacing: 40.0) {
Image(systemName: "scribble.variable")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("lapis", in: namespace)
if isExpanded {
Image(systemName: "eraser.fill")
.frame(width: 80.0, height: 80.0)
.glassEffect()
.glassEffectID("borracha", in: namespace)
}
}
}
Button("Alternar") {
withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
Estendendo Rolagem Horizontal Sob a Barra Lateral
Para permitir que o conteúdo de rolagem horizontal se estenda sob uma barra lateral ou inspetor, certifique-se de que o conteúdo da ScrollView atinja as bordas iniciais/finais do contêiner. O sistema lida automaticamente com o comportamento de rolagem sob a barra lateral quando o layout se estende até as bordas — nenhum modificador adicional é necessário.
Padrão Principal — UIKit
UIGlassEffect Básico
let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true
let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true
view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
visualEffectView.widthAnchor.constraint(equalToConstant: 200),
visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])
// Adicione conteúdo à contentView
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])
UIGlassContainerEffect para Múltiplos Elementos
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0
let containerView = UIVisualEffectView(effect: containerEffect)
let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)
Efeitos de Borda de Rolagem
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
Integração de Vidro na Barra de Ferramentas
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true // Optar por não usar fundo de vidro compartilhado
Padrão Principal — WidgetKit
Detecção de Modo de Renderização
struct MyWidgetView: View {
@Environment(\.widgetRenderingMode) var renderingMode
var body: some View {
if renderingMode == .accented {
// Modo matizado: fundo de vidro com tema branco matizado
} else {
// Modo de cor total: aparência padrão
}
}
}
Grupos de Destaque para Hierarquia Visual
HStack {
VStack(alignment: .leading) {
Text("Título")
.widgetAccentable() // Grupo de destaque
Text("Subtítulo")
// Grupo primário (padrão)
}
Image(systemName: "star.fill")
.widgetAccentable() // Grupo de destaque
}
Renderização de Imagem no Modo Matizado
Image("myImage")
.widgetAccentedRenderingMode(.monochrome)
Fundo do Contêiner
VStack { /* conteúdo */ }
.containerBackground(for: .widget) {
Color.blue.opacity(0.2)
}
Decisões de Design Principais
| Decisão | Justificativa |
|---|---|
| Envolver com GlassEffectContainer | Otimização de desempenho, permite morphing entre elementos de vidro |
Parâmetro spacing | Controla a distância de mesclagem — ajuste fino de quão próximos os elementos devem estar para se misturar |
@Namespace + glassEffectID | Permite transições de morphing suaves em mudanças na hierarquia de vistas |
Modificador interactive() | Adesão explícita para reações a toque/ponteiro — nem todo vidro deve responder |
| UIGlassContainerEffect no UIKit | Mesmo padrão de contêiner que o SwiftUI para consistência |
| Modo de renderização acentuado em widgets | O sistema aplica vidro matizado quando o usuário seleciona a Tela Inicial matizada |
Melhores Práticas
- Sempre use GlassEffectContainer ao aplicar vidro a várias vistas irmãs — ele permite morphing e melhora o desempenho de renderização
- Aplique
.glassEffect()depois de outros modificadores de aparência (frame, fonte, padding) - Use
.interactive()apenas em elementos que respondem à interação do usuário (botões, itens alternáveis) - Escolha o spacing cuidadosamente em contêineres para controlar quando os efeitos de vidro se fundem
- Use
withAnimationao alterar hierarquias de vistas para permitir transições de morphing suaves - Teste em todas as aparências — modo claro, modo escuro e modos acentuado/matizado
- Garanta contraste de acessibilidade — texto sobre vidro deve permanecer legível
Anti-Padrões a Evitar
- Usar várias vistas
.glassEffect()independentes sem um GlassEffectContainer - Aninhar muitos efeitos de vidro — degrada o desempenho e a clareza visual
- Aplicar vidro a todas as vistas — reserve para elementos interativos, barras de ferramentas e cartões
- Esquecer
clipsToBounds = trueno UIKit ao usar cantos arredondados - Ignorar o modo de renderização acentuado em widgets — quebra a aparência da Tela Inicial matizada
- Usar fundos opacos atrás do vidro — anula o efeito de translucidez
Quando Usar
- Barras de navegação, barras de ferramentas e barras de guias com o novo design do iOS 26
- Botões de ação flutuante e contêineres no estilo cartão
- Controles interativos que precisam de profundidade visual e feedback ao toque
- Widgets que devem se integrar com a aparência Liquid Glass do sistema
- Transições de morphing entre estados de UI relacionados