Este es mi primer post sobre desarrollo mobile, mi objetivo es mostrar cómo crear interfaces complejas, es decir, que tengan micro-interacciones, interacciones con gestos, animaciones, etc.
En esta instancia mostrare como montar la interface central de Tinder, donde vas Swipeando los rostros de los pretendientes dando like o unlike
Asumiré que tienes nociones sobre Swift y que ya sabes que es SwiftUI, por tanto no explicare detalles del lenguaje y no profundizare sobre SwiftUI, por lo demás ya existen un montón de posts ahi afuera que desarrollan las nociones básica de este maravilloso Framework desarrollado por apple.
Stack
Xcode 11.0 Beta 4 (11M374r)
MacOS Catalina Versión 10.15 Beta (19A512f)
Swift 5.0
Lo primero que haremos sera revisar nuestro prototipo y extraeremos sus colores y assets principales, los agregaremos a nuestro Assets.xcassets con sus correspondientes nombres.
Construyendo el Header
SwiftUI nos presenta una forma sencilla de trabajar con gradientes: LinearGradient, RadialGradient y AngularGradient. En esta ocasión trabajaremos con Linear gradient, que es una struct que nos pide un Gradient y dos UnitPoint, inicial y final.
Gradient nos pide un array de colores, que en nuestro caso sera el del gradiente izquierdo y derecho descritos anteriormente
Gradient(colors: [Color("left_gradient_color"), Color("rigth_gradient_color")])
Un UnitPoint es un punto, imagina un plano cartesiano con las coordenadas X y Y. Puedes inicializar asi:
UnitPoint(x: 0.0, y: 0.0)
Pero tambien puedes acceder a las constantes
UnitPoint.bottom
UnitPoint.bottomLeading
UnitPoint.bottomTrailing
UnitPoint.center
UnitPoint.leading
UnitPoint.top
UnitPoint.topLeading
UnitPoint.topTrailing
UnitPoint.trailing
UnitPoint.zero
Si quieres un Gradiente que vaya de izquierda a derecha utilizarías el UnitPoint.leading y el UnitPoint.trailing, generalmente estas constantes te servirán para la mayoría de los casos en los que quieras utilizar gradientes, sin embargo siempre podrás inicializar un UnitPoint con un punto arbitrario en el plano, para lograr algo exactamente como lo que estas buscando.
import SwiftUI
struct GradientHeader: View {
var body: some View {
VStack{
Text("Discover")
.font(.system(size: 30))
.bold()
.foregroundColor(.white)
.offset(x:25, y: 25)
}
.frame(minWidth:0, maxWidth: .infinity, alignment: .leading)
.frame(height: 180)
.background(LinearGradient(gradient: Gradient(colors: [Color("left_gradient_color"),Color("rigth_gradient_color")]), startPoint: .leading, endPoint: .trailing))
}
}
El resultado del código anterior nos dará como resultado lo siguiente
Botones
Los botones en SwiftUI son muy simples de declarar
Button("Click Me"){
//tap action
}
.frame(width:60, height:60)
Otra forma de declararlo
Button(action:{
//tap action
}){
Text("Click Me")
}
.frame(width:60, height:60)
La forma anterior nos permite agregar mas cosas, como Images, Stacks, etc
En esta imagen mostramos la modificación de un botón con cada linea de código que agrega un nuevo modificador a la vista.
Button("Click Me"){
//tap action
}
.frame(width:60, height:60)
.background(Color.white)
.mask(Circle())
.shadow(color: Color("Shadow"), radius: 4, x: 0, y: 5)
Una forma más avanzada de ordenar nuestros botones, es generar unos estilos derivados de ButtonStyle, así podremos inyectar estilos de manera fácil a nuestros botones solo referenciando sus respectivos nombres de estilos.
//button+styles.swift
import Foundation
import SwiftUI
public struct Rounded : ButtonStyle {
public func body(configuration: Button<Self.Label>, isPressed: Bool) -> some View {
configuration
.background(Color.white)
.mask(Circle())
.shadow(color: Color("Shadow"), radius: 4, x: 0, y: 5)
}
}
public struct Big : ButtonStyle {
public func body(configuration: Button<Self.Label>, isPressed: Bool) -> some View {
configuration
.frame(width: 60, height: 60)
}
}
extension StaticMember where Base : ButtonStyle {
public static var rounded: Rounded.Member {
StaticMember<Rounded>(Rounded())
}
public static var big: Big.Member {
StaticMember<Big>(Big())
}
}
Aislando nuestros estilos como se muestran anteriormente, nos queda una composición de nuestro botón de manera mas limpia, con la aventaja añadida que podemos combinar estilos, aquí podemos ver como combinamos el estilo de un botón grande con el de un botón redondeado.
//Crea un nuevo Documento SwiftUI
import SwiftUI
struct ContentView: View {
var body: some View {
Button("Click Me!"){
//Tap Code!!
}
.buttonStyle(.rounded)
.buttonStyle(.big)
}
}
Una vez que hemos codeado nuestro botón, crearemos una Vista que contenga todos nuestros botones, intercalando los botones pequeños y grandes como muestra nuestro prototipo, los botones de los costados tienen un pequeño desfase hacia arriba.
//Buttons.swift
import SwiftUI
struct Buttons: View {
var body: some View {
HStack(alignment: .center){
Button(action:{}){
Image("redo")
.resizable()
.frame(width: 22, height: 22)
.foregroundColor(Color("redo"))
}
.buttonStyle(.rounded)
.buttonStyle(.small)
.offset(y:-14.0)
// Agregar los otros 4 botones, intercalando .small y .big
// solo los botones de los costados tienen offset y : -14
}
.padding(.bottom, 35)
.frame(minWidth:0, maxWidth:.infinity)
}
}
El resultado de generar los botones de esta manera
Conclusión
Desarrollar vistas con SwiftUI es realmente sencillo, los desarrolladores Swift agradecerán la forma coherente que tiene SwiftUI de utilizar la potencia del lenguaje con sus nuevas características. Una cosa interesante de observar es lo parecido con react native, a los desarrolladores que vengan de este mundo, les resultara muy familiar la forma en que se construyen las interfaces; Quizás sea una excelente oportunidad para explorar el mundo del desarrollo nativo.
Se agradece cualquier critica que puedan dejar, ademas de compartir el post con desarrolladores interesados en el desarrollo Mobile.
Anexare el proyecto de Github con los contenidos del tutorial:
Tag con el avance de este post
Top comments (1)
Oh WOW! Esta cosa del SwiftUI se ve súper sencilla! Gracias por compartir el post. Besitos 💜