Artículo
Crear botones personalizados en SwiftUI
Una de las funciones clave de SwiftUI es permitir crear componentes personalizados. En este tutorial vamos a aprender a cómo crear botones personalizados en estilo para nuestra app.
Cuando queremos desarrollar aplicaciones con SwiftUI, la reutilización de componentes es clave para tener un código limpio, bien estructurado, eficiente y fácil de mantener. A continuación vamos a ver un ejemplo de creación de un componente reutilizable, un botón personalizado que podremos incorporar a diferentes vistas en nuestra aplicación.
Componentes reutilizables en SwiftUI
SwiftUI facilita el uso de componentes que pueden ser reutilizados en diferentes partes o vistas de nuestra aplicación. Por un lado, esto reduce la duplicación del código. Por otro lado, facilita el mantenimiento y la escalabilidad de nuestras aplicaciones o proyectos.
Beneficios de utilizar componentes reutilizables en nuestras aplicaciones
- Eficiencia: Ahorra tiempo al evitar tener que volver a reescribir código que puede ser idéntico o muy similar.
- Consistencia: Mantiene una apariencia y un comportamiento uniforme en toda la aplicación.
- Mantenimiento: Facilita el proceso de mejora o actualización ya que todo se encuentra en un solo lugar.
Creación de un botón personalizado
Comenzamos creando un botón personalizado en un nuevo archivo Swift. A esta vista le daremos el nombre de BotonPersonalizado. Este botón tendrá un estilo específico que lo hará destacar y será fácilmente reutilizable en cualquier otra vista que lo necesite.
struct BotonPersonalizado: View {
var texto: String
var accion: () -> Void
var body: some View {
Button(action: accion) {
Text(texto)
}
.frame(width: 400, height: 80)
.foregroundStyle(.blue)
.font(.title)
.overlay(
Capsule().stroke(
LinearGradient(
colors: [.cyan, .purple, .cyan],
startPoint: .leading,
endPoint: .trailing
),
lineWidth: 5
)
)
}
}BotonPersonalizado es una estructura que conforma al protocolo View y que recibe dos parámetros: texto y accion.
textoes un String que mostrará el texto que aparece en el botón.acciones un closure que define la acción a realizar cuando se hace clic en el botón. En este caso una "función vacía".
Como el objetivo es reutilizar el estilo del botón en diferentes pantallas de nuestra aplicación, necesitamos poder ajustar su texto y su acción según las necesidades de cada una de esas pantallas y de lo que queramos que ocurra cuando el usuario interactúe con ese botón.
Ahora solo tenemos que ir a la vista donde queremos incorporar el struct BotonPersonalizado e incorporarlo, pasando los parámetros de texto y accion como mejor nos convengan.
struct BookCardView: View {
@State private var books = Books()
@State private var title: String = ""
@State private var author: String = ""
@State private var pages: String = ""
@State private var status: Bool = false
var body: some View {
VStack(alignment: .leading) {
Text("Biblioteca 📚").font(.largeTitle.bold())
TextField("Título del libro", text: $title)
TextField("Autor", text: $author)
TextField("Número de páginas", text: $pages)
Toggle(isOn: $status) {
Text("Finalizado")
}
BotonPersonalizado(texto: "Añadir libro", accion: {
books.addLibro(title: title, author: author, pages: pages, status: status)
title = ""
author = ""
pages = ""
status = false
})
List {
ForEach(books.bookList.indices, id: \.self) { index in
let book = books.bookList[index]
VStack {
HStack {
Text("Título:").font(.subheadline)
Text(book.title).font(.subheadline.bold())
}
HStack {
Text("Autor:").font(.subheadline)
Text(book.author).font(.subheadline.bold())
}
HStack {
Text("Páginas:").font(.subheadline)
Text(book.pages).font(.subheadline.bold())
}
HStack {
Text("Estado:").font(.subheadline)
Text(book.status ? "Leído" : "No empezado")
.font(.subheadline.bold())
}
}
}
.onDelete(perform: { indexSet in
indexSet.forEach { index in
books.eliminarLibro(at: index)
}
})
}
.frame(height: 200)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
.background(
LinearGradient(gradient: Gradient(colors: [Color.blue, Color.purple]), startPoint: .top, endPoint: .bottom)
.opacity(0.4)
)
.clipShape(RoundedRectangle(cornerRadius: 20))
.frame(width: 400)
}
}De esta forma tan sencilla, podemos reutilizar componentes en diferentes vistas de una misma aplicación sin necesidad de repetir código.
