Reputation: 9419
I have a UIMenuController
with a "Delete" menu item on top of a collection view cell which is displayed when the user long presses on a cell with section 1:
@IBAction func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
let p = sender.location(in: collectionView)
guard sender.state == .began, let indexPath = self.collectionView.indexPathForItem(at: p), let cell = self.collectionView.cellForItem(at: indexPath) else { return }
if indexPath.section == 1 {
let frameInSuperView = collectionView.convert(cell.frame, to: view)
let deleteItem = UIMenuItem(title: "Delete", action: #selector(deleteCell))
UIMenuController.shared.menuItems = [deleteItem]
UIMenuController.shared.setTargetRect(frameInSuperView, in: view)
becomeFirstResponder()
UIMenuController.shared.setMenuVisible(true, animated: true)
}
}
How do I pass the index path of the cell to the function below? I need this information to delete the object from the server.
@objc internal func deleteCell(sender: UIMenuItem) {
print("delete menu item tapped! print index path of selected collection view cell?")
}
Upvotes: 3
Views: 1462
Reputation: 336
I solved this type of issue in this way:
let menuController = UIMenuController.shared
menuController.accessibilityHint = String(indexPath.row)
@objc func deleteCell(_ sender: UIMenuController) {
print("delete menu item tapped! index path? \(sender.accessibilityHint)")
}
I had using swift 4. Hope it will help.
Upvotes: 0
Reputation: 2771
As @mkeremkeskin pointed out, there's an answer to this where he linked.. but that answer is in Objective-C, here you'll find a Swift 4 version.
You can subclass the UIMenuItem
and add the indexPath to it!
I had to remove some code for it to work in my playground, but you get the idea :)
class CustomMenuItem: UIMenuItem {
var indexPath: IndexPath?
convenience init(title: String, action: Selector, indexPath: IndexPath? = nil) {
self.init(title: title, action: action)
self.indexPath = indexPath
}
}
class ViewController {
func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
let indexPath = IndexPath(item: 0, section: 1)
if indexPath.section == 1 {
let deleteItem = CustomMenuItem(title: "Delete", action: #selector(deleteCell), indexPath: indexPath)
UIMenuController.shared.menuItems = [deleteItem]
UIMenuController.shared.setMenuVisible(true, animated: true)
}
}
@objc internal func deleteCell(sender: CustomMenuItem) {
guard let indexPath = sender.indexPath else { return }
// Delete item based on indexPath
}
}
Upvotes: 2
Reputation: 644
You can subclass menu item to get the necessary object.
An example has been answered here:
Pass value through UIMenuItem of UIMenuController
Upvotes: 1
Reputation: 6085
You cannot directly pass the info along with the selector
action; instead you should store index path in a member variable which you set in your long-press handler and consume in your delete handler.
private var indexPathForDeleting: IndexPath? = nil
Don't forget to do your housekeeping and clear the variable when it's no longer needed.
Upvotes: 1