我想要在长按UITableViewCell以显示自定义UIMenuItems时弹出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;
}
但它只是显示“复制”项目,因为我只允许它和我的自定义项目。但是,自定义项目不会显示。
我意识到,我可以为单元格本身添加一个手势识别器,但这种方式会破坏UIMenuController共享实例的目的,不是吗?
答案 0 :(得分:51)
据我所知,有两个主要问题:
1)您希望tableView canPerformAction:
支持自定义选择器,而文档说它只支持UIResponderStandardEditActions
中的两个(复制和/或粘贴);
2)在您通过初始化|| action == @selector(test:)
属性添加自定义菜单选项时,不需要部件menuItems
。对于此项目选择器,检查将是自动的。
如何显示自定义菜单项并开始工作:
1)使用
修复表视图委托方法A)
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 {
}
///////////////////////////////////////////////////////
答案 1 :(得分:8)
为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()
}
}
注意:
答案 2 :(得分:2)
仅允许复制第 0 部分的第 0 行的示例
更新到 Swift 5.2
func shouldAllowCopyOn(indexPath: IndexPath) -> Bool {
if indexPath.section == 0 && indexPath.row == 0 {
return true
}
return false
}
func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
return self.shouldAllowCopyOn(indexPath: indexPath)
}
func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
if (action == #selector(UIResponderStandardEditActions.copy(_:))) {
return self.shouldAllowCopyOn(indexPath: indexPath)
}
}
func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {
if (action == #selector(UIResponderStandardEditActions.copy(_:)) && self.shouldAllowCopyOn(indexPath: indexPath)) {
if let cell = self.tableView.cellForRow(at: indexPath) as? UITableViewCell {
self.copyAction(cell: cell)
}
}
}
@objc
private func copyAction(cell: UITableViewCell) {
UIPasteboard.general.string = cell.titleLabel.text
}
答案 3 :(得分:1)
SWIFT 3:
在AppDelegate中didFinishLaunchingWithOptions:
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
}
}