# Crear botones personalizados en SwiftUI

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. 

```swift
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`.
- `texto` es un String que mostrará el texto que aparece en el botón.
- `accion` es 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.

```swift
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.
