Customizing Button with ButtonStyle
Customizing Button with ButtonStyle 관련
Updated for Xcode 15
SwiftUI has a number of styling protocols that allow us to define common styling for views such as Button
, ProgressView
, Toggle
, and more. They all work by allowing us to centralize any number of modifiers that get a view looking the way we want it, and provide modifiers that let us apply the full set of customizations in a single line.
For example, here’s a button that has its styling declared inline:
Button("Press Me") {
print("Button pressed!")
}
.padding()
.background(Color(red: 0, green: 0, blue: 0.5))
.clipShape(Capsule())
![A dark blue capsule shaped button with “Press Me” printed on it in blue.](https://hackingwithswift.com/img/books/quick-start/swiftui/customizing-button-with-buttonstyle-1~dark@2x.png)
That works fine for a single button, but if that’s the standard button design across your entire app you should consider using a custom button style instead. This means creating a new struct that conforms to the ButtonStyle
protocol, which will pass us the button’s configuration to act on however we want.
So, we could centralize those three modifiers into a single BlueButton
style, then apply it to our button like this:
struct BlueButton: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.background(Color(red: 0, green: 0, blue: 0.5))
.foregroundStyle(.white)
.clipShape(Capsule())
}
}
struct ContentView: View {
var body: some View {
Button("Press Me") {
print("Button pressed!")
}
.buttonStyle(BlueButton())
}
}
![A dark blue capsule shaped button with “Press Me” printed on it in white.](https://hackingwithswift.com/img/books/quick-start/swiftui/customizing-button-with-buttonstyle-2~dark@2x.png)
The button configuration we’re passed includes whether the button is currently being pressed or not, so we can us that to adjust our button.
For example, we could create a second style that makes the button grow when it’s being pressed down:
struct GrowingButton: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.background(.blue)
.foregroundStyle(.white)
.clipShape(Capsule())
.scaleEffect(configuration.isPressed ? 1.2 : 1)
.animation(.easeOut(duration: 0.2), value: configuration.isPressed)
}
}
struct ContentView: View {
var body: some View {
Button("Press Me") {
print("Button pressed!")
}
.buttonStyle(GrowingButton())
}
}