iOS
Swift
UIActionSheet
app development
iOS UI

How to present iOS UIActionSheet in Swift?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

UIActionSheet is deprecated, so in modern Swift code you should present an action sheet using UIAlertController with the .actionSheet style. The old title still comes up because many developers are maintaining legacy code or translating older examples, but the runtime-safe answer today is UIAlertController.

Use UIAlertController with .actionSheet

The modern equivalent of an action sheet is:

swift
1import UIKit
2
3final class ViewController: UIViewController {
4    @IBAction func showOptions(_ sender: UIButton) {
5        let sheet = UIAlertController(
6            title: "Choose Action",
7            message: "Select one of the options below.",
8            preferredStyle: .actionSheet
9        )
10
11        sheet.addAction(UIAlertAction(title: "Edit", style: .default) { _ in
12            print("Edit tapped")
13        })
14
15        sheet.addAction(UIAlertAction(title: "Delete", style: .destructive) { _ in
16            print("Delete tapped")
17        })
18
19        sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel))
20
21        present(sheet, animated: true)
22    }
23}

This is the normal solution for current iOS projects.

Why UIActionSheet Is No Longer the Right API

Older code often looked for UIActionSheet, but Apple replaced it with UIAlertController because one controller type can now represent:

  • alerts
  • action sheets

That unifies the presentation model and removes the need for delegate-heavy older APIs.

If you are reading an old tutorial that uses UIActionSheet, the migration path is not conceptual. It is mostly a direct API replacement.

iPad Requires an Anchor

On iPad, an action sheet needs a source view or bar button item. If you do not provide one, the app can crash at runtime.

swift
1import UIKit
2
3final class ViewController: UIViewController {
4    @IBOutlet weak var optionsButton: UIButton!
5
6    @IBAction func showOptions(_ sender: UIButton) {
7        let sheet = UIAlertController(
8            title: "More",
9            message: nil,
10            preferredStyle: .actionSheet
11        )
12
13        sheet.addAction(UIAlertAction(title: "Refresh", style: .default))
14        sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel))
15
16        if let popover = sheet.popoverPresentationController {
17            popover.sourceView = sender
18            popover.sourceRect = sender.bounds
19        }
20
21        present(sheet, animated: true)
22    }
23}

This is one of the most important practical details. iPhone often works with minimal setup, while iPad requires explicit presentation context.

Present from the Correct View Controller

The sheet must be presented by a view controller that is currently in the view hierarchy. If you try to present from an off-screen controller or during an invalid transition, the sheet may fail to appear or log warnings.

Reliable pattern:

  • build the UIAlertController
  • configure all actions
  • set popover anchor if needed
  • call present(_:animated:) from the active view controller

If you are in a multi-scene or container-heavy app, be especially careful about which controller owns the presentation.

Add Handlers Cleanly

Each action can attach a closure handler. Keep those handlers focused and avoid doing unrelated UI logic inline if it makes the sheet code hard to read.

swift
sheet.addAction(UIAlertAction(title: "Archive", style: .default) { [weak self] _ in
    self?.archiveCurrentItem()
})

Using [weak self] is often a good idea when the handler captures controller state, especially if the logic grows beyond one or two lines.

Legacy UIActionSheet Context

If you are maintaining very old code, you may still see UIActionSheet plus delegate methods. The migration concept is:

  • replace the sheet object with UIAlertController
  • replace delegate callbacks with action closures
  • replace old iPad presentation handling with popoverPresentationController

That usually reduces code complexity rather than increasing it.

Common Pitfalls

The biggest mistake is searching for a modern way to instantiate UIActionSheet itself. The right fix is to stop using it and switch to UIAlertController.

Another issue is forgetting iPad popover configuration for .actionSheet. That often causes crashes or presentation errors.

A third problem is presenting the sheet from the wrong controller or during an invalid lifecycle moment, which leads to warnings such as "whose view is not in the window hierarchy."

Summary

  • In modern Swift, present an action sheet with UIAlertController(preferredStyle: .actionSheet).
  • 'UIActionSheet is deprecated and should not be used in new code.'
  • Add actions with UIAlertAction and use closures for handlers.
  • On iPad, always configure the popover anchor.
  • Present from the active visible view controller to avoid hierarchy-related errors.

Course illustration
Course illustration

All Rights Reserved.