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
How to show a custom UIMenuItem for a UITableViewCell?
提问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 menuItems
property. 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:
笔记:
- This uses the new Swift 3 #selectors.
- See this answer for info on how to implement copy.
- 这使用了新的Swift 3 #selectors。
- 有关如何实现 copy 的信息,请参阅此答案。
回答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
}
}