0

I want to show a Menu with UIContextualAction. I know I cannot modify it that much so I decided to add a button when in UIContextualAction Handler and then press it programatically to show the menu. First instead of menu I decided to print or show a toast message which is working fine but when I add code for adding menu to the button, it does not work. I have added menu to a button somewhere else same way and it is working fine there, by tapping on my device, not programatically. But im not sure why my code below does not work as all im doing is tapping a button programatically and show menu. The programmatic tap does show toast so button is definitely getting tapped but menu does not show when I replace code with UIMenu. But same code works when I tap manually a UIButton.

This is what I have done so far. As I have already implemented UIMenu with a button elsewhere in the app and its working fine and now I just want same functionality with the trailing swipe gesture but when I found out, UIMenu can only be used with UIButton or UIBarButtonItem, I decided to add a button to view of UIContextualAction and programmatically press the button to show the menu like this:

  func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let actionHandler: UIContextualAction.Handler = { action, view, completion in
            // Add action here
            let button = UIButton(frame: view.bounds)
            button.showsMenuAsPrimaryAction = true
            button.addTarget(self, action: #selector(self.tapOptions), for: .touchUpInside)
            button.sendActions(for: .touchUpInside)
                        completion(true)
        }

        let action = UIContextualAction(style: .normal, title: nil, handler: actionHandler)
        action.image = UIImage(named: "testImage")
        action.backgroundColor = .black

        return UISwipeActionsConfiguration(actions: [action])
    }

And this is my tapOptions method:

  @objc func tapOptions(_ sender: UIButton) {
        let muteAction = UIAction(title: "Mute", image: UIImage(named: "Add")) { _ in
            // Perform action
            self.showToast(message: "Mute is tapped", attachTo: .top)
        }

        let deleteImage = UIImage(named: "Eye")?.withTintColor(.red)
        let deleteTitle = NSAttributedString(string: "Delete", attributes: [.foregroundColor: UIColor.red])

        let deleteAction = UIAction(title: deleteTitle.string, image: deleteImage) { _ in
            // Perform action
            self.showToast(message: "Delete is tapped", attachTo: .top)
        }
        deleteAction.setValue(deleteTitle, forKey: "attributedTitle")

        sender.menu = UIMenu(title: "", children: [muteAction, deleteAction])
    }

If I add code above, I don't see anything happening when I tap. But if I remove everything from tapOptions method and just show a toast, it works fine like this:

  @objc func tapOptions(_ sender: UIButton) {
        self.showToast(message: "Delete is tapped", attachTo: .top)
    }

So button does get tapped and it shows the toast. But it does not show a menu same way and im not sure why as to my understanding, the menu is implemented as I did somewhere else in the code and it works there on tap. Here im just tapping programatically and it shows toast if I remove menu code so that code works too. But it does not show manu when I tap programatically.

0 Answers0