Custom Button Styles
A ButtonStyle is a reusable definition of the look and feel of a Button. It gets passed a configuration with the button label and state and has to return the View for the button:
swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Views/Button/Custom-Button-Styles
import SwiftUI
struct FunkyButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.background(
LinearGradient(
gradient: Gradient(colors: [.blue, .purple]),
startPoint: .leading,
endPoint: .trailing
)
)
.foregroundColor(.white)
.clipShape(.rect(cornerRadius: 20))
.scaleEffect(configuration.isPressed ? 0.8 : 1.0)
.animation(.bouncy, value: configuration.isPressed)
}
}
extension ButtonStyle where Self == FunkyButtonStyle {
static var funky: FunkyButtonStyle {
FunkyButtonStyle()
}
}
struct CustomButtonStyleView: View {
var body: some View {
Button("Roll", systemImage: "dice") {}
.buttonStyle(.funky)
}
}
#Preview {
CustomButtonStyleView()
}
Custom gestures
PrimitiveButtonStyle is more customizable and allows to define the interaction behaviour / gestures for the button. Example
Modifying existing button styles
The system-defined Button Styles can be extended by forwarding the implementation to their .makeBody() method. Although you cannot add modifiers to the Label, but only style the View as returned by the system button style.
swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Views/Button/Custom-Button-Styles
import SwiftUI
struct TypewriterButtonStyle: PrimitiveButtonStyle {
func makeBody(configuration: Configuration) -> some View {
BorderedProminentButtonStyle()
.makeBody(configuration: configuration)
.font(.body.monospaced().bold())
.tint(Color.gray)
}
}
extension PrimitiveButtonStyle where Self == TypewriterButtonStyle {
static var typewriter: TypewriterButtonStyle {
TypewriterButtonStyle()
}
}
struct ModifiedButtonStyleExample: View {
var body: some View {
Button("Roll", systemImage: "dice") {}
.buttonStyle(.typewriter)
}
}
#Preview {
ModifiedButtonStyleExample()
}