SwiftUI Buttons & Toggles

Feb 17, 2022 3 min read
SwiftUI Buttons & Toggles

This is an up-to date documentation with examples on how to create buttons in SwiftUI. Target iOS is 15+

The basic structure of a Button is the following:

Button(action: {
    doSomething()
}) {
    Text("Road2Crypto")
}

Using Button Role

When it comes to style, you can either go fully granular style or use apple's predefined style for quicker development:

Button("Delete", role: .destructive) {
    viewModel.delete()
}

You can also add some background with:

Button("Delete", role: .destructive) {
    print("Delete")
}
.buttonStyle(.borderedProminent)
.controlSize(.large)

You can also add multiple options to a button like with:

struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Hello, World!")
                .toolbar {
                    Menu("Actions") {
                        Button("New action") {}
                        Button("Delete", role: .destructive) {}
                }
            }.navigationTitle("Buttons")
        }
    }
}

Apple gives a couple of options to design the button, you need to platy around with it to find the right spot, here's an example:

Button("New action") {}
    .tint(.green)
    .buttonStyle(.bordered)
    .buttonBorderShape(.capsule)
    .controlSize(.large)

Confirmation Dialog

Other than the new button style, iOS 15 comes with a new modifier called .confirmationDialog that you can attach to a Button for displaying a confirmation dialog.

struct DemoView: View {
    @State private var isShowingDialog = false
    var body: some View {
        Button("Delete", role: .destructive) {
            isShowingDialog = true
        }
        .buttonStyle(.borderedProminent)
        .controlSize(.large)
        .confirmationDialog("Are you sure to delete the data?", isPresented: $isShowingDialog, titleVisibility: .visible) {
 
            Button("Confirm", role: .destructive) {
                // Handle the delete action.
            }
            Button("Cancel", role: .cancel) {
 
            }
        }
    }
}

The .confirmationDialog modifier takes in a title and a binding to a Boolean value that determines whether to present the dialog. Optionally, you can indicate whether the dialog should display the title.

Customizing the Button with Materials

n iOS 15, SwiftUI introduces a material type for developers to create different types of blur effects. You can apply a blur effect to a view that appears behind another view by adding one of the following materials using the .background modifier:

  • .ultraThickMaterial
  • .thickMaterial
  • .regularMaterial
  • .thinMaterial
  • .ultraThinMaterial

Here is the sample code snippet which applies the .ultraThinMaterial:

Button(action: {}) {
    Text("Add to Cart")
        .font(.headline)
}
.padding()
.background(.ultraThinMaterial, in: Capsule())

As explained by Apple, adding a material is like inserting a translucent layer between the modified view and its background. Depending on the material you use, it will achieve a different blur effect. The following figure demonstrates the blur effect of different materials.

Toggle Button

Toggle in iOS appears in the form of switch. In iOS 15, you can configure a toggle to appear like a button by using the .toggleStyle modifier like this:

struct DemoView: View {
    @State private var isEnabled = false
 
    var body: some View {
 
        Toggle(isOn: $isEnabled) {
            Label("Airplane mode", systemImage: "airplane.circle.fill")
        }
        .padding()
        .tint(.purple)
        .controlSize(.large)
        .toggleStyle(.button)
    }
}

By setting the toggle style to .button, the toggle appears like a button. The figure below shows how it looks when the toggle is in ON/OFF state.

Great! Next, complete checkout for full access to ArturoFM.
Welcome back! You've successfully signed in.
You've successfully subscribed to ArturoFM.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info has been updated.
Your billing was not updated.