Aprende a crear aplicaciones en SwiftUI que soporten Dark Mode
Aprende a crear aplicaciones en SwiftUI que soporten Dark Mode

¿Cómo aplicar DarkMode en mis aplicaciones en SwiftUI?

Crea aplicaciones móviles que soporten Dark Mode usando SwiftUI. En el post de hoy exploramos 2 maneras diferentes, una es creando los colores en los Assets de Xcode y la otra es usando el Property Wrapper Environment de SwiftUI

SwiftBeta

Tabla de contenido


👇 SÍGUEME PARA APRENDER SWIFTUI, SWIFT, XCODE, etc 👇

Hoy en SwiftBeta vamos a aprender a cómo crear una app que soporte light y dark mode. Imagina que un usuario tiene el dark mode, el modo oscuro como preferencias en su iPhone, adaptar nuestra app y poder controlar estas dos apariencias hará que nuestros usuarios estén más contentos. Vamos a crear una vista muy sencilla, y dependiendo de la configuración que tenga el usuario, aplicaremos unos colores u otros, adaptándose a las preferencias del usuario.

Utilizaremos el Canvas para ver al momento cómo se comporta nuestra vista en estos 2 escenarios.

Creamos proyecto en Xcode

Lo primero de todo que vamos hacer es crear un proyecto, creamos una aplicación en SwiftUI, y dentro de ContentView vamos a crear la siguiente vista.

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "swift")
                .font(.system(size: 100))
                .foregroundStyle(.tint)
                .tint(.red)
            Text("¡Suscríbete a SwiftBeta! 🚀")
                .font(.largeTitle)
                .bold()
        }
        .offset(y: -100)
        .padding()
    }
}

Ahora en el Canvas vamos a habilitar para ver las dos apariencias, la light y el dark a la vez. Tan solo debemos de dar al Button Color Scheme Variants, al hacerlo vemos como en el Canvas, aunque tengamos una sola Preview, podemos ver como se comporta nuestra vista con light y dark mode, muy sencillo!

Por defecto, nosotros no hemos añadido ningún color al background de la vista, ni al Text. Y si te fijas, en light mode está utilizando el background color blanco y el text color en black. Y justo lo opuesto para el dark mode, donde el background color es black y el color del texto es white. ¿Qué ocurre si queremos customizar cómo se comporta nuestra app en estas dos apariencias? En tu app, seguro que acabaras teniendo una vista con muchos colores asignados a diferentes componentes. Para solucionarlo vamos a ver dos maneras diferentes.

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

Crear Colores en carpeta Assets

Lo primero que vamos a ver es que desde la sección de Assets podemos crear colores, es decir, hasta ahora siempre habíamos visto en el canal a usar un color de una vista directamente por código, pero podemos tener una paleta de colores bien definida dentro de nuestra sección de Assets, pudiendo ver de un simple vistazo todos los colores de nuestra app.

Al crear estos colores podemos especificar qué color queremos que aparezca para el light mode o el dark mode.

Vamos a la carpeta de Assets, y pulsamos botón derecho del ratón. Ahí seleccionamos New Color Set. Fíjate que al hacerlo aparecen dos colores, uno para cualquier apariencia, y el otro para Dark mode. Vamos a renombrar nuestro nuevo Asset, nuestro Color a largeTitleOnboardingColor, un nombre largo pero muy descriptivo. En cualquier apariencia vamos a escoger un color azulado, así que abrimos el inspector de atributos, y vamos a Universal System Colors. Aquí escogemos el color systemBlueColor. Una vez hemos seleccionado el color que queremos que aparezca en light mode, vamos a escoger otro color para el dark mode, repetimos el mismo paso y escogemos el color systemGreenColor.

Acabamos de crear nuestro primer color, ahora tan solo debemos ir a nuestro código y conectarlo de alguna manera. Volvemos a ContentView, y aquí usamos el ViewModifier foregroundStyle, importante, si no estás usando Xcode 15 te dará un error, en este caso puedes usar foregroundColor

Dentro de este ViewModifier podemos usar el color que hemos creado en nuestra sección de Assets. Fíjate, detalle importante, que al poner un . vemos un listado de colores y aparece largeTitleOnboarding (y está omitiendo el Color del final, es decir, nosotros hemos llamado a nuestro color largeTitleOnboardingColor, pero aquí nos aparece largeTitleOnboarding, detalle curioso).

Al aplicar el color, vemos automáticamente el cambio reflejado en el Canvas. Nosotros podríamos volver a la sección de Assets, y seguir creando color e incluso agrupándolos en diferentes carpetas.

Pues bien, esta es una manera sencilla de tener diferentes colores en una app en la que queremos soportar diferentes apariencias, light y dark mode. Ahora vamos a continuar y vamos a ver otra manera tocando un poco más de código.

Property Wrapper Environment

Ahora vamos a modificar el background color de nuestro VStack, vamos a identificar por código cuando un user tiene activado light o dark mode para poder decidir qué color mostrar.

Lo primero de todo, nos vamos al ContentView y añadimos la siguiente propiedad

@Environment(\.colorScheme) var colorScheme: ColorScheme

Aquí estamos usando el property wrapper environment, y estamos extrayendo el valor de colorScheme. Este property wrapper es muy útil y lo veremos más adelante ya que podemos extra como pixelLenght, scenePhase, dismiss, etc de momento nos quedamos con que colorScheme nos da la información necesaria para saber si un user está en modo light mode o dark mode.

En este caso, vamos al VStack y vamos a usar este property wrapper. Usamos el ViewModifier background y dentro de él hacemos la siguiente comprobación:

.background(colorScheme == .dark ? .yellow : .green)

De esta manera si estamos en dark mode usamos un background color de amarillo, y si no usamos el background color de verde.

Vamos a arreglar un poco esta vista, y añadimos un padding y corner radius de 20. Y este sería el resultado final.

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme: ColorScheme
    
    var body: some View {
        VStack {
            Image(systemName: "swift")
                .font(.system(size: 100))
                .foregroundStyle(.tint)
                .tint(.red)
            Text("¡Suscríbete a SwiftBeta! 🚀")
                .font(.largeTitle)
                .bold()
                .foregroundColor(.largeTitleOnboarding)
        }
        .padding()
        .background(colorScheme == .dark ? .yellow : .green)
        .cornerRadius(20)
        .offset(y: -100)
    }
}

Conclusión

Hoy hemos visto a que podemos controlar cuando usar un color u otro dependiendo de si un user está en light o dark mode. Lo hemos visto creando un color en la sección de Assets, y también lo hemos visto por código, usando el property wrapper Environment.

Y hasta aquí el video de hoy!