Длительное нажатие на UITableView

Я хотел бы долгое нажатие на UITableViewCell распечатать «меню быстрого доступа». Кто-то уже это сделал?

В частности, жест признается в UITableView ?

Сначала добавьте длинный идентификатор распознавания жестов к представлению таблицы:

 UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; lpgr.minimumPressDuration = 2.0; //seconds lpgr.delegate = self; [self.myTableView addGestureRecognizer:lpgr]; [lpgr release]; 

Затем в обработчике жестов:

 -(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { CGPoint p = [gestureRecognizer locationInView:self.myTableView]; NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"long press on table view at row %ld", indexPath.row); } else { NSLog(@"gestureRecognizer.state = %ld", gestureRecognizer.state); } } 

Вы должны быть осторожны с этим, чтобы он не мешал нормальному handleLongPress на ячейку пользователя, а также handleLongPress что handleLongPress может срабатывать несколько раз (это будет связано с изменением состояния распознавателя жестов).

Я использовал ответ Анны-Карениной, и он работает почти отлично с очень серьезной ошибкой.

Если вы используете разделы, длительное нажатие на заголовок раздела приведет к неправильному результату нажатия первой строки в этом разделе, я добавил исправленную версию ниже (включая фильтрацию фиктивных вызовов в зависимости от состояния жестов, за Предложение Анны-Карениной).

 - (IBAction)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { CGPoint p = [gestureRecognizer locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell.isHighlighted) { NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row); } } } } 

Вот поясняемая инструкция, сочетающая ответ Dawn Song и ответ Мармора.

Перетащите длинный дескриптор распознавания жестов и опустите его в свою ячейку таблицы. Он переместится в нижнюю часть списка слева.

введите описание изображения здесь

Затем подключите распознаватель жестов так же, как вы бы подключили кнопку. введите описание изображения здесь

Добавьте код из Marmor в обработчик действий

 - (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateBegan) { CGPoint p = [sender locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell.isHighlighted) { NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row); } } } 

}

Выглядит более эффективно, чтобы добавить распознаватель непосредственно в ячейку, как показано ниже:

Нажмите и удерживайте для элементов TableView, затем и сейчас

(перейдите к примеру внизу)

Ответ в Swift:

Добавьте делегат UIGestureRecognizerDelegate в свой UITableViewController.

В UITableViewController:

 override func viewDidLoad() { super.viewDidLoad() let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:") longPressGesture.minimumPressDuration = 1.0 // 1 second press longPressGesture.delegate = self self.tableView.addGestureRecognizer(longPressGesture) } 

И функция:

 func handleLongPress(longPressGesture:UILongPressGestureRecognizer) { let p = longPressGesture.locationInView(self.tableView) let indexPath = self.tableView.indexPathForRowAtPoint(p) if indexPath == nil { print("Long press on table view, not row.") } else if (longPressGesture.state == UIGestureRecognizerState.Began) { print("Long press on row, at \(indexPath!.row)") } } 

Ответ в Swift 3.0 (продолжение ответа Рики в Свифте)

Добавьте UIGestureRecognizerDelegate в ViewController

  override func viewDidLoad() { super.viewDidLoad() //Long Press let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress)) longPressGesture.minimumPressDuration = 0.5 longPressGesture.delegate = self self.tableView.addGestureRecognizer(longPressGesture) } 

И функция:

 func handleLongPress(longPressGesture:UILongPressGestureRecognizer) { let p = longPressGesture.location(in: self.tableView) let indexPath = self.tableView.indexPathForRow(at: p) if indexPath == nil { print("Long press on table view, not row.") } else if (longPressGesture.state == UIGestureRecognizerState.began) { print("Long press on row, at \(indexPath!.row)") } } 

Я собрал небольшую категорию на UITableView на основе отличного ответа Анны Карениной.

Таким образом, у вас будет удобный метод делегирования, как вы привыкли при работе с обычными табличными представлениями. Проверьте это:

 // UITableView+LongPress.h #import  @protocol UITableViewDelegateLongPress; @interface UITableView (LongPress)  @property(nonatomic,assign) id  delegate; - (void)addLongPressRecognizer; @end @protocol UITableViewDelegateLongPress  - (void)tableView:(UITableView *)tableView didRecognizeLongPressOnRowAtIndexPath:(NSIndexPath *)indexPath; @end // UITableView+LongPress.m #import "UITableView+LongPress.h" @implementation UITableView (LongPress) @dynamic delegate; - (void)addLongPressRecognizer { UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; lpgr.minimumPressDuration = 1.2; //seconds lpgr.delegate = self; [self addGestureRecognizer:lpgr]; } - (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { CGPoint p = [gestureRecognizer locationInView:self]; NSIndexPath *indexPath = [self indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { // I am not sure why I need to cast here. But it seems to be alright. [(id)self.delegate tableView:self didRecognizeLongPressOnRowAtIndexPath:indexPath]; } } } 

Если вы хотите использовать это в UITableViewController, вам, вероятно, потребуется подclass и соответствовать новому протоколу.

Он отлично работает для меня, надеюсь, что он помогает другим!

Просто добавьте UILongPressGestureRecognizer к данной ячейке прототипа в раскадровке, затем потяните жест в файл .m-файла viewController, чтобы создать метод действия. Я сделал это, как я сказал.

Swift 3, используя современный синтаксис, включая другие ответы и исключая ненужный код.

 override func viewDidLoad() { super.viewDidLoad() let recognizer = UILongPressGestureRecognizer(target: self, action: #selector(tablePressed)) tableView.addGestureRecognizer(recognizer) } @IBAction func tablePressed(_ recognizer: UILongPressGestureRecognizer) { let point = recognizer.location(in: tableView) guard recognizer.state == .began, let indexPath = tableView.indexPathForRow(at: point), let cell = tableView.cellForRow(at: indexPath), cell.isHighlighted else { return } // TODO } 

Используйте свойство timestamp UITouch в touchhesBegan, чтобы запустить таймер или остановить его, когда touchsEnded был запущен

Давайте будем гением компьютера.