Aprende a usar el ViewModifier overlay en SwiftUI
Aprende a usar el ViewModifier overlay en SwiftUI

Modificadores en SwiftUI: overlay

Los modificadores en SwiftUI permiten modificar nuestras Views de una manera muy rápida y sencilla. Por eso es muy importante conocer la gran variedad que podemos usar en SwiftUI, en este caso exploramos el ViewModifier overlay para superponer vistas.

SwiftBeta

Tabla de contenido


👇 SÍGUEME PARA APRENDER SWIFTUI, SWIFT, XCODE, etc 👇
ViewModifier overlay en SwiftUI
ViewModifier overlay en SwiftUI

Hoy en SwiftBeta vamos a ver otro modificador de SwiftUI llamado overlay. Este modificador nos permite superponer una vista encima de otra. Al final del video aprendremos a crear la siguiente vista:

CardView del ejercicio práctico que programaremos desde cero en SwiftUI
CardView del ejercicio práctico que programaremos desde cero en SwiftUI

En la card que estamos viendo, vamos usar el modificador overlay para superponer la imagen en nuestro RoundedRectangle. Esto es muy parecido al ZStack que ya vimos en uno de nuestro videos de SwiftUI del canal. Si quieres echarle un vistazo te lo dejo por aquí arriba.

Pero antes, si quieres apoyar el contenido que subo cada semana, suscríbete. De esta manera seguiré publicando contenido completamente grautito en Youtube.

Creamos el proyecto en Xcode

Lo primero de todo que vamos hacer es lo de siempre, vamos a crear un proyecto en SwiftUI. Dentro de este proyecto nos vamos a la vista ContentView y aquí en la variable body vamos a crear una vista muy sencilla.
Esta vista nos va a servir para explicar qué hace el modificador .overlay y lo vamos a comparar con ZStack. Lo primero de todo es añadir un Circle a la vista ContentView:

struct ContentView: View {
    var body: some View {
        Circle()
            .fill(.blue)
            .frame(width: 300)
 }
Código en SwiftUI usando Circle

Vamos a simular que esta vista es la típica imagen de perfil de alguna red social en la que se muestra nuestra foto. En este caso, queremos añadir un Button para poder cambiar la imagen. Para añadir este Button vamos a usar el operador .overlay.

Debajo de nuestro modificador frame añadimos el modificador overlay. Dentro del modificador overlay añadimos un Button:

struct ContentView: View {
    var body: some View {
        Circle()
            .fill(.blue)
            .frame(width: 300)
            .overlay {
                Button {
                    print("Edit Profile Image")
                } label: {
                    HStack {
                        Image(systemName: "pencil.circle.fill")
                            .resizable()
                            .scaledToFit()
                            .tint(.black)
                            .frame(width: 70)
                    }

                }
            }
    }
}
Usamos el modificador overlay por primera vez en SwiftUI

En el canvas vemos el resultado, pero no es exactamente lo que queremos, ya que el Button taparía nuestra imagen. Para modifica la posición podemos usar uno de los parámetros que acepta el modificador overlay. Si abrimos paréntesis podemos ver una serie de opciones, en nuestro caso escogemos .bottomTrailing:

struct ContentView: View {
    var body: some View {
        Circle()
            .fill(.blue)
            .frame(width: 300)
            .overlay(alignment: .bottomTrailing) {
                Button {
                    print("Edit Profile Image")
                } label: {
                    HStack {
                        Image(systemName: "pencil.circle.fill")
                            .resizable()
                            .scaledToFit()
                            .tint(.black)
                            .frame(width: 70)
                    }

                }
            }
    }
}
Añadimos el parámetros bottomTrailing para desplazar la Image abajo a la derecha

Fíjate lo sencillo que ha sido, vamos a continuar, este modificador es muy parecido a usar un ZStack, y para demostrartelo voy a reemplazar el modificador overlay por el contenedor ZStack:

struct ContentView: View {
    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            Circle()
                .fill(.blue)
                .frame(width: 300)
            Button {
                print("Edit Profile Image")
            } label: {
                HStack {
                    Image(systemName: "pencil.circle.fill")
                        .resizable()
                        .scaledToFit()
                        .tint(.black)
                        .frame(width: 70)
                }

            }
        }
    }
}
Podemos replicar el mismo comportamiento con un contenedor ZStack

El resultado es el mismo 👍. Es más, podrías mostrar los 2 ejemplos en la misma vista para ver el resultado:

struct ContentView: View {
    var body: some View {
        VStack {
            ZStack(alignment: .bottomTrailing) {
                Circle()
                    .fill(.blue)
                    .frame(width: 300)
                Button {
                    print("Edit Profile Image")
                } label: {
                    HStack {
                        Image(systemName: "pencil.circle.fill")
                            .resizable()
                            .scaledToFit()
                            .tint(.black)
                            .frame(width: 70)
                    }

                }
            }
            Circle()
                .fill(.blue)
                .frame(width: 300)
                .overlay(alignment: .bottomTrailing) {
                    Button {
                        print("Edit Profile Image")
                    } label: {
                        HStack {
                            Image(systemName: "pencil.circle.fill")
                                .resizable()
                                .scaledToFit()
                                .tint(.black)
                                .frame(width: 70)
                        }

                    }
                }
        }
    }
}
Comparamos overlay y ZStack

Una vez usado por primera vez este modificador, ahora vamos a crear una vista un poco más compleja.


Ejemplo práctico en SwiftUI

Vamos a crear el ejemplo que te mostraba al inicio del video. Vamos a borrar todo lo que tenemos en la vista ContentView y vamos a añadir el siguiente código:

struct ContentView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 4)
                .fill(.blue)
            HStack {
                VStack(alignment: .leading) {
                    
                }
                .padding(.leading, 12)
                .padding(.top, 6)
                Spacer()
            }
        }
        .frame(height: 230)
        .padding(.horizontal, 12)
    }
}
Creamos la base de nuestra View en SwiftUI

Hasta aquí nada nuevo, todo lo hemos visto en el canal. Estamos creando el esqueleto que tendrá nuestra nueva vista en SwiftUI.

Dentro del VStack que hemos creado, vamos a añadir las siguiente vistas. Al finalizar deberíamos tener una vista como la siguiente:

struct ContentView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 4)
                .fill(.blue)
            HStack {
                VStack(alignment: .leading) {
                    Text("SWIFTUI")
                        .fontWidth(.compressed)
                        .foregroundColor(.white)
                        .font(.system(size: 80, weight: .bold))
                        .padding(.bottom, -40)
                    Text("¡Suscríbete al\ncanal de SwiftBeta!")
                        .multilineTextAlignment(.center)
                        .fontWidth(.compressed)
                        .foregroundColor(.orange)
                        .font(.system(size: 26, weight: .bold))
                        .frame(width: 200, height: 100)
                    Spacer()
                    Text("SwiftBeta")
                        .fontWidth(.standard)
                        .foregroundColor(.white)
                        .font(.system(size: 18, weight: .bold))
                    
                    HStack(alignment: .lastTextBaseline) {
                        Image(systemName: "applelogo")
                            .font(.footnote)
                            .foregroundColor(.white)
                        Text("Mobile Developer")
                            .fontWidth(.standard)
                            .foregroundColor(.white)
                            .fontWeight(.regular)
                            .font(.system(size: 14))
                        
                            
                    }
                    .padding(.bottom, 12)
                }
                .padding(.leading, 12)
                .padding(.top, 6)
                Spacer()
            }
        }
        .frame(height: 230)
        .padding(.horizontal, 12)
    }
}
Añadimos más Views a nuestra CardView

Una vez hemos creado nuestra vista, vamos a usar el modificador overlay para añadir una imagen a nuestro RoundedRectangle. Añadimos el modificador overlay y dentro añadimos la Image añadimos el siguiente código:

struct ContentView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 4)
                .fill(.blue)
                .overlay {
                    Image(systemName: "figure.run")
                        .resizable()
                        .scaledToFill()
                        .frame(width: 100, height: 240)
                        .offset(x: -40)
                }
            HStack {
                VStack(alignment: .leading) {
                    Text("SWIFTUI")
                        .fontWidth(.compressed)
                        .foregroundColor(.white)
                        .font(.system(size: 80, weight: .bold))
                        .padding(.bottom, -40)
                    Text("¡Suscríbete al\ncanal de SwiftBeta!")
                        .multilineTextAlignment(.center)
                        .fontWidth(.compressed)
                        .foregroundColor(.orange)
                        .font(.system(size: 26, weight: .bold))
                        .frame(width: 200, height: 100)
                    Spacer()
                    Text("SwiftBeta")
                        .fontWidth(.standard)
                        .foregroundColor(.white)
                        .font(.system(size: 18, weight: .bold))
                    
                    HStack(alignment: .lastTextBaseline) {
                        Image(systemName: "applelogo")
                            .font(.footnote)
                            .foregroundColor(.white)
                        Text("Mobile Developer")
                            .fontWidth(.standard)
                            .foregroundColor(.white)
                            .fontWeight(.regular)
                            .font(.system(size: 14))
                        
                            
                    }
                    .padding(.bottom, 12)
                }
                .padding(.leading, 12)
                .padding(.top, 6)
                Spacer()
            }
        }
        .frame(height: 230)
        .padding(.horizontal, 12)
    }
}
Vista usando overlay enSwiftUI

Como te comentaba antes, al usar el modificador overlay podemos especificar el alineamiento de su contenido, en este caso vamos a especificar .bottomTrailing:

RoundedRectangle(cornerRadius: 4)
    .fill(.blue)
    .overlay(alignment¨.bottomTrailing) {
        Image(systemName: "figure.run")
            .resizable()
            .scaledToFill()
            .frame(width: 100, height: 240)
            .offset(x: -40)
    }
Usamos el parámetros alignment para alinear la View

De esta manera obtenemos el resultado que esperábamos. Una cardview que podemos usar en nuestras aplicaciones de SwiftUI.

Y hasta aquí el video de hoy!

Conclusión

Hoy en SwiftBeta hemos aprendido a usar el modificador overlay, este modificador nos permite superponer vistas. Como hemos visto es muy parecido al contenedor de vistas ZStack.