长按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可能会多次触发(这是由于手势识别器的状态改变)。

我使用了Anna-Karenina的答案,它的工作非常好,带有一个非常严重的错误。

如果你正在使用部分,长按章节标题会给你一个错误的结果,按下该部分的第一行,我已经添加了一个固定的版本下面(包括基于手势状态过滤虚拟调用,每安娜 – 卡列尼娜build议)。

 - (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); } } } } 

下面是黎明宋的答案和马莫尔的答案相结合的澄清说明。

拖动长按手势识别器,并将其放到您的表格单元格。 它会跳到左侧列表的底部。

在这里输入图像描述

然后按照连接button的方式连接手势识别器。 在这里输入图像描述

在操作处理程序中添加来自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) } 

而function:

 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(Ricky在Swift中的回答)

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) } 

而function:

 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)") } } 

基于Anna Karenina的出色答案,我在UITableView上放了一个小类。

像这样,您可以像处理常规表视图时一样使用方便的委托方法。 一探究竟:

 // UITableView+LongPress.h #import <UIKit/UIKit.h> @protocol UITableViewDelegateLongPress; @interface UITableView (LongPress) <UIGestureRecognizerDelegate> @property(nonatomic,assign) id <UITableViewDelegateLongPress> delegate; - (void)addLongPressRecognizer; @end @protocol UITableViewDelegateLongPress <UITableViewDelegate> - (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<UITableViewDelegateLongPress>)self.delegate tableView:self didRecognizeLongPressOnRowAtIndexPath:indexPath]; } } } 

如果你想在UITableViewController中使用它,你可能需要inheritance和遵循新的协议。

它对我很好,希望它可以帮助别人!

只需将UILongPressGestureRecognizer添加到故事板中给定的原型单元格,然后将该手势拖到viewController的.m文件以创build操作方法。 正如我所说,我做到了。

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 } 

使用touchesBegin中的UITouch timestamp属性来启动计时器,或在touchesEnded被触发时停止它