Creating UIContextualAction in Swift

In this tutorial, you will learn how to create UIContextualAction in Swift.

UIContextualAction is a class in UIKit, introduced in iOS 11.0, that you can use to define the types of actions that can be performed when the user swipes left or right on a table row.

Here are some key points about UIContextualAction:

  • It is used to create actions to display when the user swipes a table row,
  • You can use your actions to initialize a UISwipeActionsConfiguration object in your table view delegate object,
  • It has properties like titlebackgroundColorimagehandler, and style,
    • title: The title displayed on the action button,
    • backgroundColor: The background color of the action button,
    • image: The image to display in the action button,
    • handler: The handler block to execute when the user selects the action,
    • style: The style that applies to the action button.

By the end of this tutorial, you will have a working Swift code example that you can use in your mobile application.

Step 1: Setup initial TableView

To create a UITableView programmatically, you first need to initialize the table view and add it to your view controller’s view hierarchy. This involves setting up the table view’s constraints to ensure it fills the entire screen.

let tableView = UITableView()

func setupTableView() {
    view.addSubview(tableView)
    tableView.translatesAutoresizingMaskIntoConstraints = false
    tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
}

The setupTableView function is responsible for this setup, including registering the cell class with a reuse identifier for efficient memory usage. This approach allows for a dynamic and flexible UI that can be easily adjusted or modified without the need for Interface Builder.

If you want to learn more about UITableView read this tutorial.

Step 2: Conform to necessary Protocols

Next, you’ll need to conform to UITableViewDataSource and UITableViewDelegate protocols to manage the table view’s data and interactions. To load data into the table view and handle user interactions, you need to conform to UITableViewDataSource and UITableViewDelegate protocols.

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

...

}

Once your ViewController class conforms to UITableViewDataSource and UITableViewDelegate protocols, you need to implement protocol methods:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3 // For three items
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
    cell.textLabel?.text = "Item \(indexPath.row + 1)"
    return cell
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true // Allows editing for all rows
}

The UITableViewDataSource protocol methods, tableView(_:numberOfRowsInSection:) and tableView(_:cellForRowAt:), are used to specify the number of rows in the table view and to configure each cell. The UITableViewDelegate protocol method tableView(_:canEditRowAt:) allows you to enable or disable the editing of rows in the table view.

Step 3: Load Items from an Array into the Table View

To make the data loading dynamic and more flexible, you can replace the hardcoded values in the tableView(_:numberOfRowsInSection:) and tableView(_:cellForRowAt:) methods with an array of items. This approach allows you to easily update the data displayed in the table view by modifying the array

let items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7"]

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
    cell.textLabel?.text = items[indexPath.row]
    return cell
}

Step 4: Use UIContextualAction to Create Two Table View Row Action Buttons

UIContextualAction allows you to add swipe actions to each row in the table view.

By implementing the tableView(_:trailingSwipeActionsConfigurationForRowAt:) method from the UITableViewDelegate protocol, you can define actions such as delete and share that users can perform by swiping a row. Each action is represented by a UIContextualAction instance, which you can customize with a style, title, and a handler block that executes when the action is triggered.

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completionHandler) in
        // Action to perform when the delete action is triggered
        print("Delete action triggered for row \(indexPath.row)")
        completionHandler(true)
    }
    
    let shareAction = UIContextualAction(style: .normal, title: "Share") { (action, view, completionHandler) in
        // Action to perform when the share action is triggered
        print("Share action triggered for row \(indexPath.row)")
        completionHandler(true)
    }
    
    return UISwipeActionsConfiguration(actions: [deleteAction, shareAction])
}

The handlers defined in the UIContextualAction instances are triggered when the user taps on the corresponding action button. In this example, the handlers simply print a message to the console. You can customize these handlers to perform any action you need, such as deleting an item from the data source or sharing the item’s content

Complete Code Example

Here’s the complete code example based on the steps above.

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableView = UITableView()
    let cellIdentifier = "cell"
    let items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupTableView()
        tableView.dataSource = self
        tableView.delegate = self
    }
    
    func setupTableView() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
    }
    
    // MARK: - UITableViewDataSource
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
        cell.textLabel?.text = items[indexPath.row]
        return cell
    }
    
    // MARK: - UITableViewDelegate
    
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true // Allows editing for all rows
    }
    
    // UIContextualAction for swipe actions
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completionHandler) in
            print("Delete action triggered for row \(indexPath.row)")
            completionHandler(true)
        }
        
        let shareAction = UIContextualAction(style: .normal, title: "Share") { (action, view, completionHandler) in
            print("Share action triggered for row \(indexPath.row)")
            completionHandler(true)
        }
        
        return UISwipeActionsConfiguration(actions: [deleteAction, shareAction])
    }
}

Create UIContextualAction in Swift

Conclusion

I hope this tutorial was helpful for you. There are a lot more Swift code examples on this website if you check the  Swift Code Examples page.