We’ve looked at SwiftUI’s buttons briefly previously, but they are remarkably flexible and can adapt to a huge range of use cases.
The simplest way to make a button is one we’ve looked at previously: when it just contains some text you pass in the title of the button, along with a closure that should be run when the button is tapped:
Button("Delete selection") {
print("Now deleting…")
}
Of course, that could be any function rather than just a closure, so this kind of thing is fine:
struct ContentView: View {
var body: some View {
Button("Delete selection", action: executeDelete)
}
func executeDelete() {
print("Now deleting…")
}
}
There are a few different ways we can customize the way buttons look. First, we can attach a role to the button, which iOS can use to adjust its appearance both visually and for screen readers. For example, we could say that our Delete button has a destructive role like this:
Button("Delete selection", role: .destructive, action: executeDelete)
Second, we can use one of the built-in styles for buttons: .bordered
and .borderedProminent
. These can be used by themselves, or in combination with a role:
VStack {
Button("Button 1") { }
.buttonStyle(.bordered)
Button("Button 2", role: .destructive) { }
.buttonStyle(.bordered)
Button("Button 3") { }
.buttonStyle(.borderedProminent)
Button("Button 4", role: .destructive) { }
.buttonStyle(.borderedProminent)
}
If you want to customize the colors used for a bordered button, use the tint()
modifier like this:
Button("Button 3") { }
.buttonStyle(.borderedProminent)
.tint(.mint)
Important: Apple explicitly recommends against using too many prominent buttons, because when everything is prominent nothing is.
If you want something completely custom, you can pass a custom label using a second trailing closure:
Button {
print("Button was tapped")
} label: {
Text("Tap me!")
.padding()
.foregroundStyle(.white)
.background(.red)
}
SwiftUI has a dedicated Image
type for handling pictures in your apps, and there are three main ways you will create them:
Image("pencil")
will load an image called “Pencil” that you have added to your project.Image(decorative: "pencil")
will load the same image, but won’t read it out for users who have enabled the screen reader. This is useful for images that don’t convey additional important information.Image(systemName: "pencil")
will load the pencil icon that is built into iOS. This uses Apple’s SF Symbols icon collection, and you can search for icons you like – download Apple’s free SF Symbols app from the web to see the full set.By default the screen reader will read your image name if it is enabled, so make sure you give your images clear names if you want to avoid confusing the user. Or, if they don’t actually add information that isn’t already elsewhere on the screen, use the Image(decorative:)
initializer.
Because the longer form of buttons can have any kind of views inside them, you can use images like this:
Button {
print("Edit button was tapped")
} label: {
Image(systemName: "pencil")
}
If you want both text and image at the same time, you have two options. The first is provide them both to the Button
directly, like this:
Button("Edit", systemImage: "pencil") {
print("Edit button was tapped")
}
But if you want something more custom, SwiftUI has a dedicated type called Label
.
Button {
print("Edit button was tapped")
} label: {
Label("Edit", systemImage: "pencil")
.padding()
.foregroundStyle(.white)
.background(.red)
}
Both of those will show both a pencil icon and the word “Edit” side by side, which on the surface sounds exactly the same as what we’d get by using a simple HStack
. However, SwiftUI is really smart: it will automatically decide whether to show the icon, the text, or both depending on how they are being used in our layout, which makes this option a great choice.
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.