Tutoriales de SwiftUI y Swift para iOS Developers - PROGRAMACIONSWIFT.COM

Como usar Liquid Glass en SwiftUI

El diseño de interfaces de usuario evoluciona a un ritmo trepidante dentro del ecosistema de Apple. Como iOS Developer, dominar los efectos visuales de vanguardia no solo eleva la estética de tus aplicaciones, sino que mejora drásticamente la experiencia del usuario y la interacción táctil. Uno de los estilos más impactantes y demandados en la actualidad es el efecto de cristal fluido, conocido popularmente como Liquid Glass en SwiftUI. Esta técnica combina superficies traslúcidas esmeriladas con formas orgánicas en movimiento, refracciones de luz y degradados animados que reaccionan con el entorno.

En este tutorial práctico aprenderás a utilizar la programación Swift avanzada para crear un componente de Liquid Glass en SwiftUI completamente reutilizable y multiplataforma. Utilizando únicamente herramientas nativas dentro de Xcode, implementaremos este diseño para que funcione a la perfección en aplicaciones de iOS, macOS y watchOS.


Configuración del entorno de trabajo en Xcode

Para comenzar, abre Xcode y crea un nuevo proyecto de tipo App. En el menú de configuración, asegúrate de seleccionar SwiftUI como interfaz y Swift como lenguaje principal. Si deseas desarrollar una aplicación multiplataforma desde el primer instante, selecciona Multiplatform como destino inicial, o bien añade posteriormente los esquemas para macOS y watchOS.

Requisitos previos

  • Versión reciente de Xcode.
  • Conocimientos intermedios de programación Swift y SwiftUI.
  • Entorno configurado para iOS 17 o superior para aprovechar el máximo rendimiento del renderizado de gráficos.

Paso 1: Creación de la capa base de cristal traslúcido

El corazón del efecto Liquid Glass en SwiftUI reside en la superposición de capas traslúcidas que difuminan el fondo mientras capturan la luz en los bordes. SwiftUI proporciona materiales nativos como .ultraThinMaterial que simulan el cristal de forma nativa e integrada con el sistema operativo.

A continuación, crearemos la estructura básica de nuestra tarjeta de cristal:

import SwiftUI

struct GlassCardView<Content: View>: View {
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        content
            .padding(24)
            .background(
                RoundedRectangle(cornerRadius: 30)
                    .fill(.ultraThinMaterial)
            )
            .overlay(
                RoundedRectangle(cornerRadius: 30)
                    .stroke(
                        LinearGradient(
                            colors: [
                                .white.opacity(0.6),
                                .white.opacity(0.1),
                                .black.opacity(0.1),
                                .white.opacity(0.3)
                            ],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        ),
                        lineWidth: 1.5
                    )
            )
            .shadow(color: .black.opacity(0.15), radius: 20, x: 0, y: 10)
    }
}

Esta vista envolvente toma cualquier contenido en Swift y le aplica un contenedor de cristal con bordes reflectantes y sombras suaves.


Paso 2: Agregando la fluidez orgánica (El efecto líquido)

Para transformar un simple panel de cristal en un verdadero Liquid Glass en SwiftUI, necesitamos movimiento orgánico debajo o dentro de la superficie. Lograremos este efecto mezclando un TimelineView con orbes de color animados en movimiento constante dentro de un lienzo de renderizado.

Crearemos una vista dedicada al fondo líquido que simulara la fluidez:

struct LiquidBackgroundView: View {
    @State private var animate = false
    
    var body: some View {
        TimelineView(.animation) { timeline in
            let now = timeline.date.timeIntervalSinceReferenceDate
            let angle = Angle(radians: now)
            
            Canvas { context, size in
                let w = size.width
                let h = size.height
                
                let xOffset = cos(now) * 30
                let yOffset = sin(now) * 30
                
                context.fill(
                    Path(ellipseIn: CGRect(x: w * 0.2 + xOffset, y: h * 0.2 + yOffset, width: w * 0.5, height: w * 0.5)),
                    with: .color(.purple.opacity(0.7))
                )
                
                context.fill(
                    Path(ellipseIn: CGRect(x: w * 0.4 - xOffset, y: h * 0.4 - yOffset, width: w * 0.6, height: w * 0.6)),
                    with: .color(.blue.opacity(0.6))
                )
                
                context.fill(
                    Path(ellipseIn: CGRect(x: w * 0.1 + yOffset, y: h * 0.5 + xOffset, width: w * 0.4, height: w * 0.4)),
                    with: .color(.pink.opacity(0.5))
                )
            }
            .blur(radius: 50)
        }
    }
}

Este código en Swift dibuja formas geométricas que se desplazan de forma continua y suave. Al aplicar un filtro de desenfoque alto con .blur(radius: 50), las formas se fusionan creando una masa líquida luminosa en movimiento.


Paso 3: Integración final del componente Liquid Glass

Ahora combinaremos el fondo líquido animado con el contenedor de cristal traslúcido para obtener el acabado final del Liquid Glass en SwiftUI:

struct LiquidGlassContainer: View {
    var body: some View {
        ZStack {
            LinearGradient(
                colors: [Color.black, Color.indigo.opacity(0.8)],
                startPoint: .top,
                endPoint: .bottom
            )
            .ignoresSafeArea()
            
            LiquidBackgroundView()
                .ignoresSafeArea()
            
            GlassCardView {
                VStack(spacing: 16) {
                    Image(systemName: "drop.fill")
                        .font(.system(size: 48))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [.white, .cyan],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )
                    
                    Text("Liquid Glass")
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundColor(.white)
                    
                    Text("Tutorial de interfaz nativa en SwiftUI para todo el ecosistema Apple.")
                        .font(.body)
                        .multilineTextAlignment(.center)
                        .foregroundColor(.white.opacity(0.8))
                }
            }
            .padding(.horizontal, 20)
        }
    }
}

Al compilar este código en Xcode, observarás cómo el movimiento de las esferas de color tras la tarjeta crea un efecto óptico realista de refracción líquida a través del cristal esmerilado.


Adaptación para macOS y watchOS

Cualquier iOS Developer experimentado conoce la importancia de adaptar los componentes visuales a los diferentes sistemas operativos del ecosistema de Apple. Aunque el marco de trabajo SwiftUI es declarativo y unificado, existen consideraciones importantes respecto a la potencia de procesamiento y las guías de interfaz humana.

Adaptación para macOS

En macOS, el efecto Liquid Glass en SwiftUI se beneficia enormemente del tamaño de la pantalla y la potencia gráfica de los procesadores Apple Silicon. Puedes habilitar la interacción con el ratón haciendo que el reflejo de luz siga el cursor del ratón:

#if os(macOS)
extension View {
    func macHoverEffect() -> some View {
        self.onHover { hovering in
            // Lógica personalizada para ajustar opacidad al pasar el ratón
        }
    }
}
#endif

Adaptación para watchOS

En dispositivos de pantalla reducida como el Apple Watch, el consumo de batería y el rendimiento son críticos. El cálculo constante de animaciones en TimelineView puede drenar la energía rápidamente. Para watchOS, es recomendable sustituir el movimiento continuo por un degradado estático o una animación simplificada:

#if os(watchOS)
struct OptimizedWatchGlassView: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 16)
            .fill(.ultraThinMaterial)
            .overlay(
                RoundedRectangle(cornerRadius: 16)
                    .stroke(.white.opacity(0.3), lineWidth: 1)
            )
    }
}
#endif

Optimización y rendimiento para el iOS Developer

Trabajar con renderizado de capas traslúcidas, desenfoques profundos y animaciones fotograma a fotograma requiere precaución. Si abusas de estos efectos en listas o vistas compuestas con muchos elementos, la velocidad de fotogramas de tu aplicación caerá.

Buenas prácticas de rendimiento

  1. Evita anidar múltiples materiales: No coloques una vista con .ultraThinMaterial dentro de otra que ya utiliza traslucidez. Esto multiplica los pases de renderizado que la GPU debe realizar.
  2. Usa dibujo fuera de pantalla con moderación: El modificador .blur() consumirá muchos recursos si se aplica sobre contenido complejo. Aplícalo siempre sobre vistas simples como trazados vectoriales o formas geométricas.
  3. Aprovecha Instruments en Xcode: Utiliza la herramienta de profiling de Xcode para verificar que la interfaz mantenga los 60 o 120 fotogramas por segundo constantes durante las animaciones en dispositivos reales.

Resumen de características por plataforma

PlataformaRendimiento GráficoRecomendación de Implementación
iOSAltoAnimación completa con TimelineView y respuestas táctiles
macOSMuy AltoEfecto extendido a paneles laterales y soporte para eventos de ratón
watchOSLimitadoUso de materiales estáticos o animaciones de muy bajo impacto energético

Conclusión

El uso de Liquid Glass en SwiftUI permite crear interfaces fascinantes que cautivan visualmente a los usuarios. A través de este tutorial hemos comprobado cómo la programación Swift moderna y las herramientas proporcionadas por Xcode hacen posible implementar complejos efectos ópticos en pocas líneas de código.

Visited 1 times, 1 visit(s) today
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Como inicializar @Binding en SwiftUI

Related Posts