Подтвердить что ты не робот

Как показать пользовательский 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, не так ли?

4b9b3361

Ответ 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
   }
}