如何显示UITableViewCell的自定义UIMenuItem?

当我长按一个UITableViewCell显示自定义的UIMenuItem时,我想要popup的UIMenuController。

我在viewDidLoad中设置了自定义项目

UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)]; [[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]]; 

然后我设置所有正确的委托方法。

 - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } -(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { return (action == @selector(copy:) || action == @selector(test:)); } - (BOOL)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { if (action == @selector(copy:)) { // do stuff } return YES; } 

但是,它所做的是显示“复制”项目,因为我只允许它和我的自定义项目。 但是,自定义项目不会显示。

我意识到,我可以添加一个手势识别器的单元格本身,但是这种types的UIMenuController的共享实例的目的失败了,不是吗?

据我所知,有两个主要问题:

1)你期望tableView canPerformAction:支持自定义select器,而文档说,它只支持两个UIResponderStandardEditActions (复制和/或粘贴);

2)不需要部分|| action == @selector(test:) || action == @selector(test:)因为您正在通过初始化menuItems属性来添加自定义菜单选项。 对于这个项目select器,检查将是自动的。

你可以做什么来获得自定义菜单项显示和工作是:

1)修复表视图委托方法

一个)

 UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)]; [[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]]; [[UIMenuController sharedMenuController] update]; 

b)

 - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } -(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { return (action == @selector(copy:)); } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { // required } 

2)设置细胞( UITableViewCell

 -(BOOL) canPerformAction:(SEL)action withSender:(id)sender { return (action == @selector(copy:) || action == @selector(test:)); } -(BOOL)canBecomeFirstResponder { return YES; } /// this methods will be called for the cell menu items -(void) test: (id) sender { } -(void) copy:(id)sender { } /////////////////////////////////////////////////////// 

为UITableViewCell实现复制和自定义操作:

一旦在您的应用程序中,注册自定义操作:

 struct Token { static var token: dispatch_once_t = 0 } dispatch_once(&Token.token) { let customMenuItem = UIMenuItem(title: "Custom", action: #selector(MyCell.customMenuItemTapped(_:)) UIMenuController.sharedMenuController().menuItems = [customMenuItem] UIMenuController.sharedMenuController().update() } 

在您的UITableViewCell子类中,实现自定义方法:

 func customMenuItemTapped(sender: UIMenuController) { // implement custom action here } 

在你的UITableViewDelegate中 ,实现以下方法:

 override func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool { return true } override func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) -> Bool { return action == #selector(NSObject.copy(_:)) || action == #selector(MyCell.customMenuItemTapped(_:)) } override func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) { switch action { case #selector(NSObject.copy(_:)): // implement copy here default: assertionFailure() } } 

笔记:

  • 这使用新的Swift 3#select器 。
  • 有关如何执行复制的信息,请参阅此答案。

SWIFT 3:

在viewDidLoad中:

 let customMenuItem = UIMenuItem(title: "Delete", action: #selector(TableViewCell.deleteMessageActionTapped(sender:))) UIMenuController.shared.menuItems = [customMenuItem] UIMenuController.shared.update() 

在你的TableViewContoller类中:

 override func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool { return true } override func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool { return action == #selector(copy(_:)) || action == #selector(TableViewCell.yourActionTapped(sender:)) } override func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) { if action == #selector(copy(_:)) { let pasteboard = UIPasteboard.general pasteboard.string = messages[indexPath.row].text } }