Creating Action Sheets in SwiftUI: A Comprehensive Guide
Written on
SwiftUI provides a versatile interface element known as ActionSheet, allowing users to select from various options. Comparable to UIKit's UIActionSheet, it serves a similar purpose in modern iOS applications.
With the release of iOS 15, a new method for creating Action Sheets has been introduced via the confirmationDialog. This tutorial will delve into two distinct methods for implementing Action Sheets, depending on whether you're targeting iOS 15 or earlier versions.
To begin, let's set up a foundational code snippet for our practice.
struct ContentView: View {
var body: some View {
VStack(spacing: 15) {
Text("")
Button(action: {}) {
Text("Show")}
}
}
}
Using the .actionSheet Modifier
For projects targeting iOS 14 or older, the .actionSheet modifier is available. This modifier requires two key parameters: isPresented, which controls the visibility of the Action Sheet, and content, which defines the Action Sheet's content.
Inside the ContentView, create a state variable to manage the Action Sheet's display. Connect this variable to the .actionSheet modifier as shown below:
struct ContentView: View {
@State private var isPresented: Bool = false
var body: some View {
VStack(spacing: 15) {
Text("")
Button(action: {}) {
Text("Show")}
}
.actionSheet(isPresented: $isPresented) {
// Content will be added here}
}
}
To effectively use the .actionSheet, you will need to construct the older ActionSheet struct, which requires two pieces of information: the title as a SwiftUI Text, and the buttons, which should be an array of ActionSheet.Button. Let's update the code:
struct ContentView: View {
@State private var isPresented: Bool = false
var body: some View {
VStack(spacing: 15) {
Text("")
Button(action: {
isPresented = true}) {
Text("Show")}
}
.actionSheet(isPresented: $isPresented) {
ActionSheet(
title: Text("Select"),
buttons: [
.default(Text("Send Message")) {},
.destructive(Text("Remove Message")) {},
.cancel(Text("Cancel Message")) {}
]
)
}
}
}
Tapping the button updates the isPresented variable, thereby displaying the Action Sheet. This allows users to see various button styles in action.
It’s important to note that the cancel option is visually distinct, adhering to typical iOS design standards to enhance user experience.
Next, let’s implement actions for the Action Sheet buttons to display messages based on user selection. Update the code as follows:
struct ContentView: View {
@State private var isPresented: Bool = false
@State private var message: String = ""
var body: some View {
VStack(spacing: 15) {
Text(message)
Button(action: {
isPresented = true}) {
Text("Show")}
}
.actionSheet(isPresented: $isPresented) {
ActionSheet(
title: Text("Select"),
buttons: [
.default(Text("Send Message")) {
message = "Message Sent"},
.destructive(Text("Remove Message")) {
message = "Message Removed"},
.cancel(Text("Cancel Message")) {}
]
)
}
}
}
This adds a state variable for the message that updates based on the button pressed. The cancel button remains unchanged.
For the final source code, visit GitHub.
Using the .confirmationDialog Modifier
If you are targeting iOS 15 or later, consider using the more flexible .confirmationDialog modifier. This approach allows you to omit the title if desired and facilitates the direct addition of SwiftUI buttons.
Let’s adapt our previous example to utilize confirmationDialog:
struct ContentView: View {
@State private var isPresented: Bool = false
@State private var message: String = ""
var body: some View {
VStack(spacing: 15) {
Text(message)
Button(action: {
isPresented = true}) {
Text("Show")}
}
.confirmationDialog("Select", isPresented: $isPresented, titleVisibility: .hidden) {
Button("Send Message") {
message = "Message Sent"}
Button("Remove Message", role: .destructive) {
message = "Message Removed"}
Button("Cancel Message", role: .cancel) {}
}
}
}
The updated code functions similarly, with the title hidden, and buttons directly embedded in the content.
Here’s how it appears when you run the application.
The source code is also available on GitHub.
May the code be with you, -Arc