Los Button
son uno de los elementos más utilizados en cualquier aplicación, y por eso es muy importante definir su look & feel, es decir, su estilo: color de texto, color de fondo, fuente, forma, tamaño… Y cómo estas propiedades cambian cuando el botón está deshabilitado o el usuario lo está presionando.
En este artículo vamos a ver cómo podemos personalizar los botones en SwiftUI. Y lo vamos a hacer de una manera muy elegante, tal y como lo hace Apple en el API de SwiftUI.
Al final, podremos tener un botón que luzca diferente en sus tres estados: normal, mientras se pulsa o cuando está deshabilitado.
Uso básico:
Comencemos añadiendo un simple botón:
struct ContentView: View {
var body: some View {
Button("Tap me!") {
// Action code here
}
}
}
A continuación, si queremos modificar colores, fuente o forma, podríamos optar por utilizar los modifiers
como en cualquier otra SwiftUI-View:
struct ContentView: View {
var body: some View {
Button("Tap me!") {
// Action code here
}
.padding(24)
.font(.system(.title, design: .monospaced))
.frame(height: 50)
.foregroundColor(.white)
.background(Color.blue.opacity(0.7))
.cornerRadius(4)
}
}
Llegados a este punto, nos podemos plantear extraer este botón personalizado en su propia vista, PrimaryButton
:
struct PrimaryButton: View {
let title: String
let action: () -> Void
var body: some View {
Button(title) {
action()
}
.padding(24)
.font(.system(.title, design: .monospaced))
.frame(height: 50)
.foregroundColor(.white)
.background(Color.blue.opacity(0.7))
.cornerRadius(4)
}
}
Sin embargo, todavía nos queda cambiar su look & feel cuando está deshabilitado o cuando lo pulsamos.
Antes de hacer estos cambios, veamos cómo el API de SwiftUI asigna los diferentes estilos a los botones:
struct ContentView: View {
var body: some View {
HStack {
Button("Plain") {
// Action
}
.buttonStyle(PlainButtonStyle())
Button("Borderless") {
// Action
}
.buttonStyle(BorderlessButtonStyle())
Button("Default") {
// Action
}
.buttonStyle(DefaultButtonStyle())
}
}
}
Tanto PlainButtonStyle
, como BorderlessButtonStyle
o DefaultButtonStyle
son estilos predefinidos en iOS. En macOS, tendríamos otras dos opciones más: LinkButtonStyle
y BorderedButtonStyle
Creando tu propio ButtonStyle
:
SwiftUI permite personalizar los botones de una manera muy elegante y reutilizable. Basta con crear un nuevo struct
que se conforma al protocolo ButtonStyle
. La ventaja de hacerlo de esta manera es que puedes modificar el label
del botón tanto como quieres. Por ejemplo, para modificar el color del texto o cualquier otra característica cuando el usuario pulsa el botón.
El único requisito de este protocolo es implementar una función makeBody(configuration:)
. Acepta un parámetro Configuration
que podemos utilizar para saber si el botón está pulsado.
struct PrimaryButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(24)
.font(.system(.title, design: .monospaced))
.frame(height: 50)
.foregroundColor(.white)
.background(
// Comprobamos si el botón está pulsado y
// utilizamos un color diferente
// 👇👇👇
configuration.isPressed ? Color.blue : Color.blue.opacity(0.7)
)
.cornerRadius(4)
}
}
struct ContentView: View {
var body: some View {
Button("Tap me!") {
// Action
}
.buttonStyle(PrimaryButtonStyle())
}
}
Hasta ahora, en este artículo estoy modificando solamente el
background
color, pero podemos modificar cualquier valor que queramos. Por ejemplo, si el botón tuviese unshadow
(sombra), cuando estuviese pulsado podríamos hacer que la sombra desapareciese. Y así con cualquier propiedad, como el color del texto, el tamaño, su forma…
Si también queremos modificar el aspecto del botón cuando éste está disabled
(deshabilitado), tenemos que crear una SwiftUI-View anidada para poder leer su propiedad de entorno isEnabled
:
struct PrimaryButtonStyle: ButtonStyle {
struct Button: View {
let configuration: ButtonStyle.Configuration
@Environment(\.isEnabled) private var isEnabled: Bool
// Asignamos diferentes colores dependiendo si el botón
// está pulsado, deshabilitado o en su estado por defecto
// 👇👇👇
var color: Color {
if configuration.isPressed {
return .blue
} else if !isEnabled {
return .gray
} else {
return Color.blue.opacity(0.7)
}
}
var body: some View {
configuration.label
.padding(24)
.font(.system(.title, design: .monospaced))
.frame(height: 50)
.foregroundColor(.white)
.background(color) // 👈 Utilizamos el color
.cornerRadius(4)
}
}
func makeBody(configuration: Configuration) -> some View {
PrimaryButtonStyle.Button(configuration: configuration)
}
}
struct ContentView: View {
var body: some View {
Button("Tap me!") {
// Action
}
.buttonStyle(PrimaryButtonStyle())
}
}
Conclusión
Como ves, para crear un botón totalmente personalizado en SwiftUI, lo mejor es crear tu propio estilo y asignarlo al SwiftUI Button
mediante el método .buttonStyle()
Así, eres totalmente libre de modificar cualquier valor en función del estado del botón: color de fondo, color de texto, forma, corner radius, sombra…
Si te ha resultado útil el post me haría mucha ilusión que lo compartieses en tus redes sociales. Puedes utilizar los botones de aquí abajo si te resulta más fácil
👇👇👇