长按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被触发时停止它