NEW: Join my free 100 Days of SwiftUI challenge today! >>

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)
            .background(backgroundColor)
            .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 },
        .cancel()
    ])
}

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.

LEARN SWIFTUI FOR FREE I have a massive, free SwiftUI video collection on YouTube teaching you how to build complete apps with SwiftUI – check it out!

BUY OUR BOOKS
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: 5.0/5