opción
HogarHogar Skill Otros liquid-glass-design

liquid-glass-design

affaan-m/ECC affaan-m/ECC

Implementar el sistema de diseño «Liquid Glass» de Apple para iOS 26+ con materiales de cristal dinámicos, desenfoque, reflejos y transformaciones interactivas en SwiftUI, UIKit y WidgetKit.

...Expandir todo
7
Tiempo actualizado 12 de octubre de 2026

Sistema de diseño Liquid Glass (iOS 26)

Patrones para implementar Liquid Glass de Apple, un material dinámico que difumina el contenido que hay detrás, refleja el color y la luz del contenido circundante y reacciona al tacto y a las interacciones con el puntero. Abarca la integración con SwiftUI, UIKit y WidgetKit.

Cuándo activarlo

  • Al crear o actualizar aplicaciones para iOS 26 y versiones posteriores con el nuevo lenguaje de diseño
  • Al implementar botones, tarjetas, barras de herramientas o contenedores con estilo de cristal
  • Al crear transiciones de transformación entre elementos de cristal
  • Aplicar efectos de Liquid Glass a los widgets
  • Migrar los efectos de desenfoque o «material» existentes a la nueva API de Liquid Glass

Patrón básico — SwiftUI

Efecto de cristal básico

La forma más sencilla de añadir Liquid Glass a cualquier vista:

Text("¡Hola, mundo!")
    .font(.title)
    .padding()
    .glassEffect()  // Por defecto: variante normal, forma de cápsula

Personalización de la forma y el tono

Text("¡Hola, mundo!")
    .font(.title)
    .padding()
    .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))

Opciones clave de personalización:

  • .regular — efecto de cristal estándar
  • .tint(Color) — añade un matiz de color para destacar
  • .interactive() — reacciona a las interacciones táctiles y del puntero
  • Forma: .capsule (por defecto), .rect(cornerRadius:), .circle

Estilos de botones de cristal

Button("Haz clic aquí") { /* acción */ }
    .buttonStyle(.glass)

Button("Importante") { /* acción */ }
    .buttonStyle(.glassProminent)

GlassEffectContainer para varios elementos

Envuelve siempre varias vistas de cristal en un contenedor para mejorar el rendimiento y facilitar la transición:

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()
    }
}

El parámetro «spacing» controla la distancia de fusión: los elementos más cercanos fusionan sus formas de cristal.

Unir efectos de cristal

Combina varias vistas en una única forma de cristal con 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 ? "group1" : "group2", namespace: namespace)
        }
    }
}

Transiciones de morphing

Crea un efecto de transformación suave cuando los elementos de cristal aparecen o desaparecen:

@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("pencil", in: namespace)

        if isExpanded {
            Image(systemName: "eraser.fill")
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectID("eraser", in: namespace)
        }
    }
}

Button("Toggle") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)

Ampliar el desplazamiento horizontal por debajo de la barra lateral

Para permitir que el contenido de desplazamiento horizontal se extienda por debajo de una barra lateral o un inspector, asegúrate de que el contenido de ScrollView llegue a los bordes inicial y final del contenedor. El sistema gestiona automáticamente el comportamiento de desplazamiento por debajo de la barra lateral cuando el diseño se extiende hasta los bordes; no se necesita ningún modificador adicional.

Patrón básico — UIKit

Efecto 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)
])

// Añadir contenido a 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 varios 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)

Efectos en los bordes de desplazamiento

scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true

Integración del efecto «Glass» en la barra de herramientas

let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // Desactivar el fondo de cristal compartido

Patrón básico — WidgetKit

Detección del modo de renderizado

struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // Modo con tinte: fondo de cristal con tinte blanco y tema
        } else {
            // Modo a todo color: apariencia estándar
        }
    }
}

Grupos de acento para la jerarquía visual

HStack {
    VStack(alignment: .leading) {
        Text("Título")
            .widgetAccentable()  // Grupo de acento
        Text("Subtítulo")
            // Grupo principal (por defecto)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // Grupo de acento
}

Representación de imágenes en modo de acento

Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)

Fondo del contenedor

VStack { /* contenido */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }

Decisiones clave de diseño

Decisión Justificación
Envolvente GlassEffectContainer Optimización del rendimiento; permite la transición entre elementos de cristal
Parámetrode espaciado Controla la distancia de fusión: ajusta con precisión la proximidad que deben tener los elementos para fusionarse
@Namespace + glassEffectID Permite transiciones fluidas de transformación al cambiar la jerarquía de vista
Modificadorinteractive() Activación explícita de las reacciones al tacto o al puntero: no todos los elementos «glass» deben responder
UIGlassContainerEffect en UIKit Mismo patrón de contenedor que en SwiftUI para mantener la coherencia
Modo de representación con acento en los widgets El sistema aplica cristal tintado cuando el usuario selecciona la pantalla de inicio tintada

Prácticas recomendadas

  • Utiliza siempre GlassEffectContainer al aplicar el efecto de cristal a varias vistas hermanas: permite la transición y mejora el rendimiento de la representación
  • Aplica .glassEffect() después de otros modificadores de apariencia (marco, fuente, relleno)
  • Utiliza .interactive() solo en elementos que respondan a la interacción del usuario (botones, elementos conmutables)
  • Elige cuidadosamente el espaciado en los contenedores para controlar cuándo se fusionan los efectos de cristal
  • Utiliza withAnimation al cambiar las jerarquías de vistas para permitir transiciones de transformación fluidas
  • Realiza pruebas con diferentes estilos de apariencia: modo claro, modo oscuro y modos con acentos o tintes
  • Asegúrate de que haya contraste para la accesibilidad: el texto sobre el cristal debe seguir siendo legible

Antipatrones que hay que evitar

  • Utilizar varias vistas .glassEffect() independientes sin un GlassEffectContainer
  • Anidar demasiados efectos de cristal: degrada el rendimiento y la claridad visual
  • Aplicar el efecto de cristal a todas las vistas: resérvalo para elementos interactivos, barras de herramientas y tarjetas
  • Olvidarse de establecer clipsToBounds = true en UIKit al utilizar radios en las esquinas
  • Ignorar el modo de representación con acentos en los widgets: altera el aspecto tintado de la pantalla de inicio
  • Utilizar fondos opacos detrás del efecto «glass»: anula el efecto de translucidez

Cuándo utilizarlo

  • Barras de navegación, barras de herramientas y barras de pestañas con el nuevo diseño de iOS 26
  • Botones de acción flotantes y contenedores tipo tarjeta
  • Controles interactivos que requieren profundidad visual y respuesta táctil
  • Widgets que deben integrarse con el aspecto «Liquid Glass» del sistema
  • Transiciones de transformación entre estados relacionados de la interfaz de usuario
Ver en GitHub
---
name: liquid-glass-design
description: Implement Apple's Liquid Glass design system for iOS 26+ with dynamic glass materials, blur, reflection, and interactive morphing in SwiftUI, UIKit, and WidgetKit.
---

# Liquid Glass Design System (iOS 26)

Patterns for implementing Apple's Liquid Glass — a dynamic material that blurs content behind it, reflects color and light from surrounding content, and reacts to touch and pointer interactions. Covers SwiftUI, UIKit, and WidgetKit integration.

## When to Activate

- Building or updating apps for iOS 26+ with the new design language
- Implementing glass-style buttons, cards, toolbars, or containers
- Creating morphing transitions between glass elements
- Applying Liquid Glass effects to widgets
- Migrating existing blur/material effects to the new Liquid Glass API

## Core Pattern — SwiftUI

### Basic Glass Effect

The simplest way to add Liquid Glass to any view:

```swift
Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // Default: regular variant, capsule shape
```

### Customizing Shape and Tint

```swift
Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
```

Key customization options:
- `.regular` — standard glass effect
- `.tint(Color)` — add color tint for prominence
- `.interactive()` — react to touch and pointer interactions
- Shape: `.capsule` (default), `.rect(cornerRadius:)`, `.circle`

### Glass Button Styles

```swift
Button("Click Me") { /* action */ }
    .buttonStyle(.glass)

Button("Important") { /* action */ }
    .buttonStyle(.glassProminent)
```

### GlassEffectContainer for Multiple Elements

Always wrap multiple glass views in a container for performance and morphing:

```swift
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()
    }
}
```

The `spacing` parameter controls merge distance — closer elements blend their glass shapes together.

### Uniting Glass Effects

Combine multiple views into a single glass shape with `glassEffectUnion`:

```swift
@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 ? "group1" : "group2", namespace: namespace)
        }
    }
}
```

### Morphing Transitions

Create smooth morphing when glass elements appear/disappear:

```swift
@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("pencil", in: namespace)

        if isExpanded {
            Image(systemName: "eraser.fill")
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectID("eraser", in: namespace)
        }
    }
}

Button("Toggle") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
```

### Extending Horizontal Scrolling Under Sidebar

To allow horizontal scroll content to extend under a sidebar or inspector, ensure the `ScrollView` content reaches the leading/trailing edges of the container. The system automatically handles the under-sidebar scrolling behavior when the layout extends to the edges — no additional modifier is needed.

## Core Pattern — UIKit

### Basic UIGlassEffect

```swift
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)
])

// Add content to 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 for Multiple Elements

```swift
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)
```

### Scroll Edge Effects

```swift
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
```

### Toolbar Glass Integration

```swift
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // Opt out of shared glass background
```

## Core Pattern — WidgetKit

### Rendering Mode Detection

```swift
struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // Tinted mode: white-tinted, themed glass background
        } else {
            // Full color mode: standard appearance
        }
    }
}
```

### Accent Groups for Visual Hierarchy

```swift
HStack {
    VStack(alignment: .leading) {
        Text("Title")
            .widgetAccentable()  // Accent group
        Text("Subtitle")
            // Primary group (default)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // Accent group
}
```

### Image Rendering in Accented Mode

```swift
Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)
```

### Container Background

```swift
VStack { /* content */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }
```

## Key Design Decisions

| Decision | Rationale |
|----------|-----------|
| GlassEffectContainer wrapping | Performance optimization, enables morphing between glass elements |
| `spacing` parameter | Controls merge distance — fine-tune how close elements must be to blend |
| `@Namespace` + `glassEffectID` | Enables smooth morphing transitions on view hierarchy changes |
| `interactive()` modifier | Explicit opt-in for touch/pointer reactions — not all glass should respond |
| UIGlassContainerEffect in UIKit | Same container pattern as SwiftUI for consistency |
| Accented rendering mode in widgets | System applies tinted glass when user selects tinted Home Screen |

## Best Practices

- **Always use GlassEffectContainer** when applying glass to multiple sibling views — it enables morphing and improves rendering performance
- **Apply `.glassEffect()` after** other appearance modifiers (frame, font, padding)
- **Use `.interactive()`** only on elements that respond to user interaction (buttons, toggleable items)
- **Choose spacing carefully** in containers to control when glass effects merge
- **Use `withAnimation`** when changing view hierarchies to enable smooth morphing transitions
- **Test across appearances** — light mode, dark mode, and accented/tinted modes
- **Ensure accessibility contrast** — text on glass must remain readable

## Anti-Patterns to Avoid

- Using multiple standalone `.glassEffect()` views without a GlassEffectContainer
- Nesting too many glass effects — degrades performance and visual clarity
- Applying glass to every view — reserve for interactive elements, toolbars, and cards
- Forgetting `clipsToBounds = true` in UIKit when using corner radii
- Ignoring accented rendering mode in widgets — breaks tinted Home Screen appearance
- Using opaque backgrounds behind glass — defeats the translucency effect

## When to Use

- Navigation bars, toolbars, and tab bars with the new iOS 26 design
- Floating action buttons and card-style containers
- Interactive controls that need visual depth and touch feedback
- Widgets that should integrate with the system's Liquid Glass appearance
- Morphing transitions between related UI states

Todos los archivos

1 archivos

Instalar liquid-glass-design

Descarga y descomprime los archivos de habilidades en tu directorio .claude/skills/.

Descargar ZIP

Clona el repositorio y copia los archivos de la habilidad a tu proyecto.

git clone https://github.com/affaan-m/ECC/tree/main/skills/liquid-glass-design # Copy SKILL.md to your .claude/skills/ directory

Copiar Copiar
Configuración rápida: Copia la carpeta de la habilidad en .claude/skills/ Claude detectará y utilizará automáticamente la habilidad
Repositorio affaan-m/ECC

Habilidades relacionadas

v4-new-features
Tiempo actualizado 4 de agosto de 2026
multica-creating-agents
Tiempo actualizado 12 de agosto de 2026
pixijs-application
Tiempo actualizado 4 de agosto de 2026
tilemaps
Tiempo actualizado 4 de agosto de 2026
OR