ios 如何为 UITableViewCell 显示自定义 UIMenuItem?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12290828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:00:13  来源:igfitidea点击:

How to show a custom UIMenuItem for a UITableViewCell?

iosuitableviewuimenucontroller

提问by leberwurstsaft

I want the UIMenuController that pops up when I long-press a UITableViewCell to show custom UIMenuItems.

我想要在我长按 UITableViewCell 时弹出的 UIMenuController 来显示自定义 UIMenuItems。

I set up the custom item in viewDidLoad

我在 viewDidLoad 中设置了自定义项

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

And then I set all the right delegate methods.

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

- (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;
}

But all it does, is show the "Copy" item, since I only allow it and my custom item. The custom item, however, won't show up.

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

I realize, I could add a gesture recognizer to the cell itself, but that kind of defeats the purpose of the shared instance of UIMenuController, doesn't it?

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

回答by A-Live

As far as I understand there are two main problems:

据我了解,有两个主要问题:

1) you expect tableView canPerformAction:to support custom selectors while the documentation says it supports only two of UIResponderStandardEditActions(copy and/or paste);

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

2) there's no need for the part || action == @selector(test:)as you are adding the custom menu options by initializing menuItemsproperty. For this items selectors the check will be automatical.

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

What you can do to get the custom menu item displayed and work is:

你能做些什么来获取自定义菜单项显示的工作是:

1) Fix the table view delegate methods with

1)修复表视图委托方法

a)

一种)

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

b)

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) Setup the cells (subclassing UITableViewCell) with

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 {

}
///////////////////////////////////////////////////////

回答by Senseful

To implement copy and a custom action for UITableViewCell:

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

Oncein your application, register the custom action:

一旦在你的应用程序,注册自定义动作:

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()
}

In your UITableViewCellsubclass, implement the custom method:

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

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

In your UITableViewDelegate, implement the following methods:

在你的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()
    }
}

Notes:

笔记:

回答by Maksim Kniazev

SWIFT 3:

快速 3:

In AppDelegate didFinishLaunchingWithOptions:

在 AppDelegate didFinishLaunchingWithOptions 中:

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

in your TableViewContoller Class:

在您的 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
   }
}