As of iOS 16, you can do it, albeit with a horizontally laid out edit menu, or, alternatively with long-press gesture, neither of which which the user may anticipate.
In the first case you provide the UIMenu to the edit menu delegate method, and in the latter, you use the context menu's delegate menu. For the horizontal menu, the shorter the menu names, the better, especially if you have more than 2 or 3 items, so the user doesn't have to click the right triangle at the end to expose more items.
The delegate methods respectively return a UIMenu, which you can create right in the delegate method, or you can set it up to reuse a mention that's triggered, perhaps with a pop-up UIButton() inside the tableView cell, that way you get better coverage in case the user doesn't tap the button itself.
Method 1: Custom 'edit' menu (e.g. present horizontal menu):
var editMenuInteraction : UIEditMenuInteraction! = nil
override func viewDidLoad() {
editMenuInteraction = UIEditMenuInteraction(delegate: self)
}
extension MyViewController: UIEditMenuInteractionDelegate {
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
let myAction = UIAction(title: "Action1", image: UIImage(systemName: "bell"), identifier: nil) { action in
print("MyAction tapped")
}
let anotherAction = UIAction(title: "Action2", image: UIImage(systemName: "person"), identifier: nil) { action in
print("AnotherAction tapped")
}
.
.
.
return UIMenu(title: "", children: [myAction, anotherAction])
}
}
extension MyViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.addInteraction(editMenuInteraction)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let interaction = editMenuInteraction {
let rect = tableView.rectForRow(at: indexPath)
let absoluteRect = tableView.convert(rect, to: tableView.superview)
let configuration = UIEditMenuConfiguration(identifier: nil, sourcePoint: absoluteRect.origin)
interaction.presentEditMenu(with: configuration)
}
}
}
Method 2: Context Menu (e.g. long press gesture on cell)
// In your cellForRowAt tableView delegate method:
let interaction = UIContextMenuInteraction(delegate: self)
cell?.addInteraction(interaction)
extension MyViewController: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
let myAction = UIAction(title: "MyAction", image: UIImage(systemName: "bell"), identifier: nil) { action in
print("MyAction tapped")
}
let anotherAction = UIAction(title: "AnotherAction", image: UIImage(systemName: "person"), identifier: nil) { action in
print("AnotherAction tapped")
}
.
.
.
return UIMenu(title: "", children: [myAction, anotherAction])
}
}
}