Antworten:
Fügen Sie zuerst den Gestenerkenner für langes Drücken zur Tabellenansicht hinzu:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];
Dann im Gestenhandler:
-(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);
}
}
Sie müssen damit vorsichtig sein, damit das normale Tippen des Benutzers auf die Zelle nicht beeinträchtigt wird. Beachten Sie auch, dass dies handleLongPress
möglicherweise mehrmals ausgelöst wird (dies ist auf Änderungen des Status der Gestenerkennung zurückzuführen).
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) ...
.
UITableView
, nicht an den UITableViewCell
... anzuhängen. )
Ich habe die Antwort von Anna-Karenina verwendet und sie funktioniert fast hervorragend mit einem sehr schwerwiegenden Fehler.
Wenn Sie Abschnitte verwenden und lange auf den Abschnittstitel drücken, erhalten Sie ein falsches Ergebnis beim Drücken der ersten Zeile in diesem Abschnitt. Ich habe unten eine feste Version hinzugefügt (einschließlich der Filterung von Dummy-Anrufen basierend auf dem Gestenstatus pro Anna-Karenina Vorschlag).
- (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);
}
}
}
}
Antwort in Swift 5 (Fortsetzung von Rickys Antwort in Swift)
Fügen Sie das
UIGestureRecognizerDelegate
Ihrem ViewController hinzu
override func viewDidLoad() {
super.viewDidLoad()
//Long Press
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPressGesture.minimumPressDuration = 0.5
self.tableView.addGestureRecognizer(longPressGesture)
}
Und die Funktion:
@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)")
}
}
Hier finden Sie geklärte Anweisungen, die Dawn Songs Antwort und Marmors Antwort kombinieren.
Ziehen Sie einen langen Press Gestenerkenner und legen Sie ihn in Ihrer Tabellenzelle ab. Es springt zum Ende der Liste auf der linken Seite.
Schließen Sie dann den Gestenerkenner genauso an, wie Sie eine Schaltfläche anschließen würden.
Fügen Sie den Code von Marmor im Aktionshandler hinzu
- (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);
}
}
}
}}
Es scheint effizienter zu sein, den Erkenner wie hier gezeigt direkt zur Zelle hinzuzufügen:
Tippen und halten Sie für TableView-Zellen, damals und heute
(Scrollen Sie zum Beispiel unten)
Antwort in Swift:
Fügen Sie UIGestureRecognizerDelegate
Ihrem UITableViewController einen Delegaten hinzu.
Innerhalb von 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)
}
Und die Funktion:
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)")
}
}
Ich habe eine kleine Kategorie auf UITableView zusammengestellt, basierend auf Anna Kareninas hervorragender Antwort.
Auf diese Weise haben Sie eine bequeme Delegierungsmethode, wie Sie es gewohnt sind, wenn Sie mit normalen Tabellenansichten arbeiten. Hör zu:
// 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];
}
}
}
Wenn Sie dies in einem UITableViewController verwenden möchten, müssen Sie wahrscheinlich eine Unterklasse erstellen und das neue Protokoll einhalten.
Es funktioniert großartig für mich, hoffe es hilft anderen!
Swift 3-Antwort mit moderner Syntax, Einbeziehung anderer Antworten und Eliminierung nicht benötigten Codes.
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
}
Fügen Sie einfach UILongPressGestureRecognizer zu der angegebenen Prototypzelle im Storyboard hinzu und ziehen Sie die Geste in die .m-Datei von viewController, um eine Aktionsmethode zu erstellen. Ich habe es geschafft, wie ich sagte.
Verwenden Sie die UITouch-Zeitstempeleigenschaft in touchBegan, um einen Timer zu starten oder zu stoppen, wenn touchEnded ausgelöst wurde