Câu trả lời:
Đầu tiên, thêm trình nhận dạng cử chỉ nhấn dài vào chế độ xem bảng:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];
Sau đó, trong xử lý cử chỉ:
-(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);
}
}
Bạn phải cẩn thận với điều này để nó không can thiệp vào thao tác gõ bình thường của người dùng và cũng lưu ý rằng handleLongPress
có thể bắn nhiều lần (điều này sẽ do thay đổi trạng thái nhận dạng cử chỉ).
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) ...
.
UITableView
, chứ không phải UITableViewCell
...)
Tôi đã sử dụng câu trả lời của Anna-Karenina và nó hoạt động gần như tuyệt vời với một lỗi rất nghiêm trọng.
Nếu bạn đang sử dụng các phần, nhấn và giữ tiêu đề phần sẽ cho bạn kết quả sai khi nhấn hàng đầu tiên trên phần đó, tôi đã thêm một phiên bản cố định bên dưới (bao gồm lọc các cuộc gọi giả dựa trên trạng thái cử chỉ, mỗi Đề nghị Anna-Karenina).
- (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);
}
}
}
}
Trả lời trong Swift 5 (Tiếp tục câu trả lời của Ricky trong Swift)
Thêm vào
UIGestureRecognizerDelegate
ViewContoder của bạn
override func viewDidLoad() {
super.viewDidLoad()
//Long Press
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPressGesture.minimumPressDuration = 0.5
self.tableView.addGestureRecognizer(longPressGesture)
}
Và chức năng:
@objc 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 == UIGestureRecognizer.State.began {
print("Long press on row, at \(indexPath!.row)")
}
}
Dưới đây là hướng dẫn được làm rõ kết hợp câu trả lời của Dawn Song và câu trả lời của Marmor.
Kéo một Trình nhận dạng cử chỉ dài và thả nó vào Bảng di động của bạn. Nó sẽ nhảy xuống cuối danh sách bên trái.
Sau đó kết nối bộ nhận dạng cử chỉ giống như cách bạn kết nối một nút.
Thêm mã từ Marmor trong trình xử lý hành động
- (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);
}
}
}
}
Có vẻ hiệu quả hơn để thêm bộ nhận dạng trực tiếp vào ô như hiển thị ở đây:
Chạm và giữ cho các ô của TableView, sau đó và ngay bây giờ
(cuộn đến ví dụ ở phía dưới)
Trả lời bằng Swift:
Thêm đại biểu UIGestureRecognizerDelegate
vào UITableViewControll của bạn.
Trong UITableViewCont kiểm soát:
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)
}
Và chức năng:
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)")
}
}
Tôi kết hợp một danh mục nhỏ trên UITableView dựa trên câu trả lời xuất sắc của Anna Karenina.
Như thế này, bạn sẽ có một phương thức ủy nhiệm thuận tiện như bạn đã quen khi xử lý các chế độ xem bảng thông thường. Kiểm tra xem nó:
// 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];
}
}
}
Nếu bạn muốn sử dụng điều này trong UITableViewCont kiểm soát, có lẽ bạn cần phải phân lớp và tuân thủ giao thức mới.
Nó hoạt động rất tốt cho tôi, hy vọng nó sẽ giúp người khác!
Trả lời Swift 3, sử dụng cú pháp hiện đại, kết hợp các câu trả lời khác và loại bỏ mã không cần thiết.
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
}
Chỉ cần thêm UILongPressGestureRecognizer vào ô nguyên mẫu đã cho trong bảng phân cảnh, sau đó kéo cử chỉ vào tệp .m của viewContoder để tạo phương thức hành động. Tôi đã làm nó như tôi đã nói.
Sử dụng thuộc tính dấu thời gian UITouch trong touchesBegan để khởi chạy bộ đếm thời gian hoặc dừng nó khi chạm vào Đã bị bắn