Jawaban:
Pertama-tama tambahkan pengenal isyarat pers yang panjang ke tampilan tabel:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];
Kemudian pada penangan isyarat:
-(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);
}
}
Anda harus berhati-hati dengan ini sehingga tidak mengganggu ketukan normal pengguna sel dan juga mencatat yang handleLongPress
mungkin menyala beberapa kali (ini akan disebabkan oleh perubahan status pengenalan isyarat).
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) ...
.
UITableView
, bukan UITableViewCell
...)
Saya telah menggunakan jawaban Anna-Karenina, dan itu bekerja hampir hebat dengan bug yang sangat serius.
Jika Anda menggunakan bagian, menekan lama judul bagian akan memberi Anda hasil yang salah dengan menekan baris pertama pada bagian itu, saya telah menambahkan versi tetap di bawah ini (termasuk pemfilteran panggilan tiruan berdasarkan status gerakan, per Saran 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);
}
}
}
}
Answer in Swift 5 (Lanjutan dari jawaban Ricky di Swift)
Tambahkan
UIGestureRecognizerDelegate
ke ViewController Anda
override func viewDidLoad() {
super.viewDidLoad()
//Long Press
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPressGesture.minimumPressDuration = 0.5
self.tableView.addGestureRecognizer(longPressGesture)
}
Dan fungsinya:
@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)")
}
}
Ini adalah instruksi yang diklarifikasi yang menggabungkan jawaban Dawn Song dan jawaban Marmor.
Seret Recognizer Gerakan Tekan lama dan letakkan di Table Cell Anda. Ini akan melompat ke bagian bawah daftar di sebelah kiri.
Kemudian hubungkan pengenal gesture dengan cara yang sama seperti Anda menghubungkan tombol.
Tambahkan kode dari Marmor di penangan tindakan
- (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);
}
}
}
}
Tampaknya lebih efisien untuk menambahkan pengenal langsung ke sel seperti yang ditunjukkan di sini:
Ketuk & Tahan untuk Sel TableView, Lalu dan Sekarang
(gulir ke contoh di bagian bawah)
Jawab di Swift:
Tambahkan delegasi UIGestureRecognizerDelegate
ke UITableViewController Anda.
Dalam 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)
}
Dan fungsinya:
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)")
}
}
Saya mengumpulkan sedikit kategori tentang UITableView berdasarkan jawaban Anna Karenina yang luar biasa.
Seperti ini, Anda akan memiliki metode delegasi yang nyaman seperti yang biasa Anda lakukan ketika berhadapan dengan tampilan tabel biasa. Saksikan berikut ini:
// 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];
}
}
}
Jika Anda ingin menggunakan ini dalam UITableViewController, Anda mungkin perlu subkelas dan menyesuaikan dengan protokol baru.
Ini sangat bagus untuk saya, semoga membantu orang lain!
Swift 3 menjawab, menggunakan sintaksis modern, memasukkan jawaban lain, dan menghilangkan kode yang tidak dibutuhkan.
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
}
Cukup tambahkan UILongPressGestureRecognizer ke sel prototipe yang diberikan di storyboard, lalu tarik gerakan ke file .m viewController's .m untuk membuat metode tindakan. Saya membuatnya seperti yang saya katakan.
Gunakan properti cap waktu UITouch dalam sentuhan. Mulai untuk meluncurkan timer atau menghentikannya ketika disentuh.