如何显示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 } }