Как показать пользовательский UIMenuItem для UITableViewCell?
Я хочу, чтобы UIMenuController появлялся, когда я долгое время нажимаю UITableViewCell для отображения пользовательских UIMenuItems.
Я настраиваю пользовательский элемент в 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, не так ли?
Ответы
Ответ 1
Насколько я понимаю, есть две основные проблемы:
1) вы ожидаете, что tableView canPerformAction:
будет поддерживать пользовательские селектора, в то время как в документации говорится, что он поддерживает только два из UIResponderStandardEditActions
(копирование и/или вставка);
2) нет необходимости в части || action == @selector(test:)
, поскольку вы добавляете параметры пользовательского меню, инициализируя свойство menuItems
. Для этих переключателей элементов проверка будет автоматической.
Что вы можете сделать, чтобы отобразить и работать пользовательский элемент меню:
1) Исправьте методы делегата представления таблицы с помощью
а)
UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)];
[[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]];
[[UIMenuController sharedMenuController] update];
б)
- (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 {
}
///////////////////////////////////////////////////////
Ответ 2
Чтобы реализовать копию и пользовательское действие для 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()
}
}
Примечания:
Ответ 3
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
}
}