5

I am using following method to show menu on long press in UITableViewCell.

I have need to pass a value pressing Delete menu Item to -(void)numberDelete method.

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {

    if(gestureRecognizer.state == UIGestureRecognizerStateBegan) {

        CGPoint p = [gestureRecognizer locationInView: self.pullTableView];
        NSIndexPath *indexPath = [self.pullTableView indexPathForRowAtPoint:p];
        if(indexPath != nil) {

            [self becomeFirstResponder];
            NSInteger *row = indexPath.row;

            //need to pass this row value through @selector(numberDelete:)

            UIMenuItem *delete = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(numberDelete:)];

            UIMenuController *menu = [UIMenuController sharedMenuController];
            [menu setMenuItems:[NSArray arrayWithObjects:delete, nil]];
            [menu setTargetRect:[self.pullTableView rectForRowAtIndexPath:indexPath] inView:self.pullTableView];
            [menu setMenuVisible:YES animated:YES];
        }

    }

}

-(void)numberDelete:(id)sender {
   //receive value of row here
}

-(BOOL)canBecomeFirstResponder {
    return YES;
}

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(customDelete:) ){
        return YES;
    }
    return NO;
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89

3 Answers3

4

So simple, just create a class of type UIMenuItem, add property in it, and use your UIMenuItem class instead of actual UIMenuItem. See how.

Create a class say MyMenuItem of type UIMenuItem.

MyMenuItem.h

#import <UIKit/UIKit.h>

@interface MyMenuItem : UIMenuItem
@property(nonatomic, strong)NSIndexPath *indexPath;
@end

MyMenuItem.m

#import "MyMenuItem.h"

@implementation MyMenuItem

@end

And then

{
    MyMenuItem *deleteMenuItem = [[MyMenuItem alloc] initWithTitle:@"Delete" action:@selector(numberDelete:)];
    deleteMenuItem.indexPath=indexPath;//Assign to property

    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setMenuItems:[NSArray arrayWithObjects:deleteMenuItem, nil]];
    [menu setTargetRect:[self.pullTableView rectForRowAtIndexPath:indexPath] inView:self.pullTableView];
    [menu setMenuVisible:YES animated:YES];
}



-(void)numberDelete:(id)sender {
   //receive value of row here. The sender in iOS 7 is an instance of UIMenuController.
   UIMenuController *targetSender = (UIMenuController *)sender ;
   MyMenuItem *menuItem=(MyMenuItem *)[targetSender.menuItems firstObject]; 

   NSLog(@"%d",menuItem.indexPath.row); 
}

I hope it helps.

Cheers.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • On iOS 7, The sender is an instance of UIMenuController instead of MyMenuItem, but, you can get the MyMenuItem from [(UIMenuController *)sender.menuItems firstObject] – bandw Oct 11 '14 at 02:58
2

Modified version of the accepted answer in Swift 4

MenuItemWithIndexPath.swift:

class MenuItemWithIndexPath: UIMenuItem {
    var indexPath: IndexPath?

    init(title: String, action: Selector, indexPath: IndexPath) {
        super.init(title: title, action: action)
        self.indexPath = indexPath
    }
}

Usage:

let menu = UIMenuController.shared
menu.menuItems = [MenuItemWithIndexPath(title: "Delete", action: #selector(numberDelete(sender:)), indexPath: indexPath)]
menu.setTargetRect(tableView.rectForRow(at: indexPath), in: tableView)
menu.setMenuVisible(true, animated: true)


@objc func numberDelete(sender:UIMenuController) {
    if let menuItem = sender.menuItems?.first as? MenuItemWithIndexPath,
        let indexPath = menuItem.indexPath {
        print("delete at indexPath: \(indexPath)")
    }
}
torof
  • 368
  • 1
  • 12
0

I solved this type of issue in this way:

 self.becomeFirstResponder()
 let deleteMenuItem = UIMenuItem(title: ConstantString.title_delete, action: #selector(deleteItem(_:)))
 let menuController = UIMenuController.shared
 menuController.menuItems = [deleteMenuItem]
 menuController.accessibilityHint = String(indexPath.row)
 menuController.setMenuVisible(true, animated: true)


@objc func deleteItem(_ sender: UIMenuController) {
     print("delete menu item tapped! index path? \(sender.accessibilityHint)")
}

I had using swift 4. Hope it will help.

Nomanur
  • 266
  • 5
  • 7