Creating Dynamic Action Sheets with SwiftUI: A Comprehensive Guide
Written on
Introduction to SwiftUI's Action Sheets
SwiftUI provides a powerful component known as ActionSheet, allowing developers to present users with a range of choices or actions. Similar to UIKit's UIActionSheet, it enhances user interaction by offering a simple interface for selections.
With the release of iOS 15, Apple introduced the more versatile confirmationDialog, which streamlines the process of creating Action Sheets. This tutorial will guide you through two methods of implementing Action Sheets, tailored for either iOS 14 or iOS 15.
Let's start with a basic structure to practice with:
struct ContentView: View {
var body: some View {
VStack(spacing: 15) {
Text("")
Button(action: {
}) {
Text("Show")}
}
}
}
Utilizing the .actionSheet Modifier
For those targeting iOS 14 or earlier, the .actionSheet modifier is available. This modifier requires two critical parameters: isPresented, which determines when the Action Sheet will show, and content, where the contents of the Action Sheet are defined.
Within the ContentView, create a state variable to manage the Action Sheet's presentation. Bind this variable to the .actionSheet modifier as illustrated 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) {
}
}
}
To implement the .actionSheet modifier, work with the older ActionSheet struct, which necessitates two parameters: the title (as a SwiftUI Text) and buttons (an array of ActionSheet.Button). Modify your existing code accordingly:
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")) {}]
)
}
}
}
Pressing the button changes isPresented to true, triggering the Action Sheet's display. Populate the buttons array with various styles and run the code. Click the "Show" button to see how the Action Sheet presents these buttons.
The cancel button is positioned separately, adhering to iOS design standards, ensuring a consistent user experience.
Next, let's add functionality to the ActionSheet buttons. The goal is to show different messages based on the selected button. 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 code introduces a new state variable that updates its content based on button selection. The cancel button remains inactive after being pressed. Run the application to test how the displayed message changes with each button tap.
You can find the complete source code on GitHub.
Transitioning to .confirmationDialog Modifier
For applications targeting iOS 15 or later, the .confirmationDialog modifier offers a superior approach to creating Action Sheets. This method allows for more flexibility, such as hiding the title if desired, and eliminates the need for the old ActionSheet struct.
Let's adjust our previous example to incorporate 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) {}
}
}
}
This implementation functions similarly to the previous one but includes the option to hide the title. The buttons are directly incorporated within the content, allowing for straightforward styling using button roles.
Explore the final code on GitHub.
The first video title is "SwiftUI in Action: A Deep Dive into Action Sheets and Confirmation Dialog" - This video provides an in-depth look at how to effectively utilize Action Sheets and confirmation dialogs in SwiftUI applications.
The second video title is "How to Create Action Sheets on iOS with SwiftUI (Xcode)" - This tutorial covers the step-by-step process of implementing Action Sheets in SwiftUI.
May your code be with you,
- Arc