Button is a control to initiate action in SwiftUI. Button view provides a label and action. Action can be a function or a closure which does something when user taps on the button. Button view takes space needed to show its content and have many options of customization.
Let’s start this exploration of button with an example.
Easiest way to create a button is by providing a string label along with a closure for action.
We will make our button increment a counter value and show the counter reading in a Text view.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button("Here is a button") {
counter += 1
}
}
.navigationTitle("DevTechie")
}
}
}
Here we are passing action as a closure but we can call a function instead and passing the name of the function inside action parameter.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button("Here is a button", action: buttonClickFunction)
}
.navigationTitle("DevTechie")
}
}
func buttonClickFunction() {
counter += 1
}
}
Button provides another overload which takes label as parameter and label can be any view so we have flexibility to create a completely custom button.
Signature looks like this:
Button(action:, label: )
Let’s update our example.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button {
counter += 1
} label: {
VStack {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.padding()
.foregroundColor(.white)
.background(Color.orange, in: RoundedRectangle(cornerRadius: 10))
}}
.navigationTitle("DevTechie")
}
}
}
If we don’t include layout view inside the label parameter for Button then system uses HStack as layout view.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}}
.navigationTitle("DevTechie")
}
}
}
Button provides buttonStyle modifier used to style buttons. We have few predefined button styles.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.buttonStyle(.borderedProminent)}
.navigationTitle("DevTechie")
}
}
}
bordered buttonStyle:
.buttonStyle(.bordered)
borderless buttonStyle:
.buttonStyle(.borderless)
Button provides button role, which is a way to provide a description of a button’s purpose. For example, destructive role indicate that button’s action is destructive like deleting certain information.
If button has style along with the button role, default style for the role is applied automatically.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button(role: .destructive) {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.buttonStyle(.bordered)}
.navigationTitle("DevTechie")
}
}
}
Along with ButtonStyle, we can also use controlSize modifier to change the amount of padding for the button.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button(role: .destructive) {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.buttonStyle(.bordered)
.controlSize(.mini)}
.navigationTitle("DevTechie")
}
}
}
.controlSize(.regular)
.controlSize(.large)
Tint is another modifier used to change button’s appearance and it’s behavior is slightly different when combined with buttonStyle.
Tint modifier without buttonStyle:
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.tint(.orange)
}
.navigationTitle("DevTechie")
}
}
}
Tint modifier with buttonStyle.
struct DevTechieButtonExample: View {
@State private var counter = 0
var body: some View {
NavigationView {
VStack {
Text("Button was tapped \(counter) times.")
Button {
counter += 1
} label: {
Image(systemName: "arrowtriangle.up.fill")
Text("Tap to count")
}
.buttonStyle(.bordered)
.tint(.orange)
}
.navigationTitle("DevTechie")
}
}
}
buttonBorderShape modifier is used to set button’s shape. We can create button with capsule , roundedRectangle and rectangle shapes.
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
.tint(.orange)
.buttonBorderShape(.roundedRectangle)
.buttonBorderShape(.roundedRectangle(radius: 0)) // rectangle
disabled modifier is used to disable the button. For example, we can use disabled modifier to make sure we have all the validations passed in a form before letting user submit the form to the backend.
struct DevTechieButtonExample: View {
@State private var username: String = ""
@State private var password: String = ""
@State private var isValid = false
var body: some View {
NavigationView {
VStack {
TextField("Enter username", text: $username) {
if !username.isEmpty && !password.isEmpty {
isValid = true
}
}
.textFieldStyle(.roundedBorder)
SecureField("Enter password", text: $password) {
if !username.isEmpty && !password.isEmpty {
isValid = true
}
}
.textFieldStyle(.roundedBorder)
Button {
print("Logged in")
} label: {
Image(systemName: "lock.shield")
Text("Login")
}
.buttonStyle(.bordered)
.buttonBorderShape(.roundedRectangle(radius: 100))
.tint(.orange)
.disabled(!isValid)
}
.padding()
.navigationTitle("DevTechie")
}
}
}
With that we have reached the end of this article. Thank you once again for reading. Don’t forget to subscribe our newsletter at https://www.devtechie.com