How can I send a UILongPressGesture programmatically?
Import <UIKit/UIGestureRecognizerSubclass.h>
and manually set the state
property as appropriate to the sequence of states you need to simulate. This will cause the added target/action pairs to be called. After each time manually setting the state, you must let the run loop run in order for the messages to be dispatched.
For the UILongPressGestureRecognizer
, to get the correct sequence of states as is found in an actual, 'touch, hold, drag, release' sequence of gestures, I wrote the following code in a UIViewController
subclass inside viewDidLoad
.:
UILongPressGestureRecognizer *r = [[UILongPressGestureRecognizer alloc] init];
[self.view addGestureRecognizer:r];
[r addTarget:self action:@selector(recognize:)];
r.state = UIGestureRecognizerStateBegan;
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
r.state = UIGestureRecognizerStateChanged;
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
r.state = UIGestureRecognizerStateEnded;
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
[r reset];
I imagine this would be risky in production code (you may wish afterwards to call reset
but I found no difference between doing so or not in my testing), but if your use case is automated testing to verify that the targets and actions have been set correctly this may meet your needs.
Swift Programmatically Launch a UILongPressGesture
I found a much cleaner solution to the problem at hand - Replacing the desired button with a UIView
containing its own UILongPressGestureRecognizer
. I set this gesture's minimumPressDuration
to 0 so it behaves equivalently to a button's touchDown
event. This new gesture uses the same longPress
function from the original question without requiring any additional code to trigger.
Programmatically change the state of a UILongPressGestureRecognizer
You're getting this error because by default, when you import UIKit into your implementation file, it imports UIGestureRecognizer.h, which publicly declares its state property as readonly. If you want to be able to set this property, you have to import UIGestureRecognizerSubclass.h, which redeclares this property as readwrite. Be warned, this is meant for use within a subclass of UIGestureRecognizer, and I don't know enough about how this works under the hood to say this usage is safe.
#import <UIKit/UIGestureRecognizerSubclass.h>
Start UIGestureRecognizer programmatically
You can always call the method on its own.
For example, you've added the selector
- (void) userCellDragged:(UIPanGestureRecognizer)sender;
For your pan gesture recognizer.
You could call this from anywhere in the view by simply adding
[self userCellDragged:nil];
Remember to add a parameter to this method something like:
if (sender == nil) {
// Triggered programmatically
}
else {
// proceed as normal
}
how UILongPressGestureRecognizer works
you have to use this code to intialized gesture
UILongPressGestureRecognizer *gesture1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(celllongpressed:)];
[gesture1 setDelegate:self];
[gesture1 setMinimumPressDuration:1];
[self addGestureRecognizer:gesture1];
and to target method use this
-(void)celllongpressed:(UIGestureRecognizer *)longPress
{
}
UILongPressGestureRecognizer sending action twice
You should handle long press gesture recognizer's state. UILongPressGestureRecognizer's action invokes on it's state changes. So you are receiving it first time when state == UIGestureRecognizerStateBegan and second time when its UIGestureRecognizerStateEnded.
You need something like:
if (recognizer.state == UIGestureRecognizerStateEnded)
{
//your action
}
UIButton Long Press Event
You can start off by creating and attaching the UILongPressGestureRecognizer
instance to the button.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];
And then implement the method that handles the gesture
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(@"Long Press");
}
}
Now this would be the basic approach. You can also set the minimum duration of the press and how much error is tolerable. And also note that the method is called few times if you after recognizing the gesture so if you want to do something at the end of it, you will have to check its state and handle it.
Related Topics
The Proper Way of Doing Chain Animations
Swift Spritekit Facebook Share Button
Add Button at the End of Collection View in Storyboard
How to Save Custom Objects in Array and Store It in Nsuserdefaults - Iphone
How to Resolve iOS Link Errors with Opencv
How to Integrate Payu Money in Swift
Apple Watchkit Simulator Issue: Sperrorinvalidbundlenogizmobinarymessage
How to Set Uibutton Type in Uibutton Subclass
How to Set the Accessibility Label for a Particular Segment of a Uisegmentedcontrol
Is Float, Double, Int an Anyobject
Refresh Only the Custom Header Views in a Uitableview
Detox: iOS Simulator How to Confirm Alert Message
Storyboard Won't Update in Simulator
Enabling Facebook Breaking Changes Feb 2013: Login Does Not Work
Xamarin.iOS Binding Libraries/Native Frameworks
How to Remove the Bottom Gap of Uipageviewcontroller
Swift - How to Open Specific View Controller When Push Notification Received