UILongPressGestureRecognizer on UITableViewCell - double call
Instead of disabling it, what you probably need to do is check the gesture recognizer's state
property and only display the next view controller if the state is UIGestureRecognizerStateBegan
(or UIGestureRecognizerStateEnded
).
You'll need to change your method to accept the gesture recognizer as a parameter (and also update the @selector
parameter) and check it's state:
UILongPressGestureRecognizer *longPressTap =
[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(memberListWithSearchOptions:)]; //colon at end
//...
- (void)memberListWithSearchOptions:(UILongPressGestureRecognizer *)lpt
{
if (lpt.state == UIGestureRecognizerStateBegan)
//or check for UIGestureRecognizerStateEnded instead
{
//display view controller...
}
}
Long press on UITableView
First add the long press gesture recognizer to the table view:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];
Then in the gesture handler:
-(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);
}
}
You have to be careful with this so that it doesn't interfere with the user's normal tapping of the cell and also note that handleLongPress
may fire multiple times (this will be due to the gesture recognizer state changes).
How to make tableViewCell handle both tap and longPress?
Don't add the UILongPressGestureRecognizer
to Cell
. Add it to UITableView
in viewDidLoad
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(sender:)))
tableView.addGestureRecognizer(longPress)
Get the touched cell index by
@objc private func handleLongPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began {
let touchPoint = sender.location(in: tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
// your code here, get the row for the indexPath or do whatever you want
}
}
}
Instead of UITapGestureRecognizer
use didSelectRowAtIndexPath
is a better way
UILongPressGestureRecognizer gets called twice when pressing down
UILongPressGestureRecognizer is a continuous event recognizer. You have to look at the state to see if this is the start, middle or end of the event and act accordingly. i.e. you can throw away all events after the start, or only look at movement as you need. From the Class Reference:
Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement). The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted.
Now You Can Track The State Like This
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(@"UIGestureRecognizerStateEnded");
//Do Whatever You want on End of Gesture
}
else if (sender.state == UIGestureRecognizerStateBegan){
NSLog(@"UIGestureRecognizerStateBegan.");
//Do Whatever You want on Began of Gesture
}
}
How to pause/disable UILongPressGestureRecognizer on a UITableViewCell while in editmode
You should implement the UIGestureRecognizerDelegate delegate for this method:
gestureRecognizer:shouldReceiveTouch:
In the method, check if you're editing the table and return NO if you are.
Tim
How deselect UITableViewCell on long press?
Make a Global previousIndexPath
Previous selected Index path
// Global variable
var previousIndexPath : IndexPath = IndexPath()
@objc func handleLongPress(longPressGesture:UILongPressGestureRecognizer) {
let p = longPressGesture.location(in: self.tblListView)
let indexPath = self.tblListView.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)")
// Edited - Add this to reset cell when more than one selected
if !previousIndexPath.isEmpty {
// Reset the Cell
let cell = self.tblListView.cellForRow(at: previousIndexPath!) as! GroupDetailTableViewCell
cell.btnDeleteMember.isHidden = true
}
let cell = self.tblListView.cellForRow(at: indexPath!) as! GroupDetailTableViewCell
cell.btnDeleteMember.isHidden = previousIndexPath == indexPath ?
true : false // This will make the Select and Deselect
previousIndexPath = indexPath
}
}
}
Long press gesture on UITableView
Change this:
let touchPoint = longPressGestureRecognizer.location(in: self.view)
To this:
let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
You're looking for a gesture inside your UITableView
not your UIView
.
Related Topics
Store Time Efficiently in Firebase Database
Unrecognized Error in Mapview (Ios)
Position a Subview on the Edge of a Circular Shaped View
Duet - Merge 2 Videos Side by Side
Determine Percentage of Visibility of Horizontal Collectionview Cells on Screen
Module Compiled with Swift 5.0.1 Cannot Be Imported by the Swift 5.1 Compiler
Why Self.Locationmanager Stopupdatinglocation Doesn't Stop Location Update
Add Custom Cordova Plugin to Ibm Worklight 6.1
String Replace Phone Number iOS Swift
iOS Library to Convert Powerpoint Presentations into Images
Handing Firebase + Facebook Login Process
Show Data in Uipickerview Second Component Based on First Component Selection
How to Switch to Speaker Output When Bluetooth Headsets Are Connected
How to Print Out a Property's Contents Using Xcode Debugger
How to Access User Defined Runtime Attribute from the 'Sender' Object
Could Not Cast Value of Type 'Uiview' (0X112484Eb0) to 'Skview' (0X111646718)
How to Take Uiimage of Avcapturevideopreviewlayer Instead of Avcapturephotooutput Capture