FREE TRIAL: Accelerate your app development career with Hacking with Swift+! >>

Showing multiple options with ActionSheet

Paul Hudson    @twostraws   

SwiftUI gives us Alert for presenting important announcements with one or two buttons, and sheet() for presenting whole views on top of the current view, but it also gives us ActionSheet: an alternative to Alert that lets us add many buttons.

Visually alerts and action sheets are very different: on iPhones, alert appear in the center of the screen and must actively be dismissed by choosing a button, whereas action sheets slide up from the bottom, can contain multiple buttons, and can be dismissed by tapping on Cancel or by tapping outside of the action sheet.

Apart from their presentation and differing numbers of buttons, action sheets and alerts share a lot of functionality. Both are created by attaching a modifier to our view hierarchy – alert() for alerts and actionSheet() for action sheets – both get shown automatically by SwiftUI when a condition is true, both use the same kind of button, and both have some built-in default styles for those buttons: default(), cancel(), and destructive().

To demonstrate action sheets being used, we first need a basic view that toggles some sort of condition. For example, this shows some text, and tapping the text changes a Boolean:

struct ContentView: View {
    @State private var showingActionSheet = false
    @State private var backgroundColor = Color.white

    var body: some View {
        Text("Hello, World!")
            .frame(width: 300, height: 300)
            .onTapGesture {
                self.showingActionSheet = true

Now for the important part: we need to add another modifier to the text, creating and showing an action sheet when we’re ready.

Just like alert(), we have an actionSheet() modifier that accepts two parameters: a binding that decides whether the action sheet is currently presented or not, and a closure that provides the action sheet that should be shown – usually provided as a trailing closure.

We provide our action sheet with a title and message, then an array of buttons. These are stacked up vertically on the screen in the order you provide, and it’s generally a good idea to include a cancel button at the end – yes, you can cancel by tapping elsewhere on the screen, but it’s much better to give users the explicit option!

So, add this modifier to your text view:

.actionSheet(isPresented: $showingActionSheet) {
    ActionSheet(title: Text("Change background"), message: Text("Select a new color"), buttons: [
        .default(Text("Red")) { self.backgroundColor = .red },
        .default(Text("Green")) { self.backgroundColor = .green },
        .default(Text("Blue")) { self.backgroundColor = .blue },

When you run the app, you should find that tapping the text causes the action sheet to slide over, and tapping its options should cause the text’s background color to change.

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for iOS devs who want to become complete senior developers — from October 18th to 24th. Learn how to apply iOS app architecture patterns through a series of lectures and practical coding sessions.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.4/5

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.