Simultaneous gesture recognition for specific gestures
Make sure your class implements UIGestureRecognizerDelegate
class YourViewController: UIViewController, UIGestureRecognizerDelegate ...
Set the gesture's delegate
to self
yourGesture.delegate = self
Add delegate function to your class
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if (gestureRecognizer is UIPanGestureRecognizer || gestureRecognizer is UIRotationGestureRecognizer) {
return true
} else {
return false
}
}
Simultaneous gesture recognizers in Iphone SDK
It was really easy:
At first we should create class, that implements UIGestureRecognizerDelegate
protocol:
@interface MyGestureDelegate : NSObject <UIGestureRecognizerDelegate>
@implementation MyGestureDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return YES;
}
And use it like this:
UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSwipeGestureLeft:)];
[self.view addGestureRecognizer:swipeGestureLeft];
swipeGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[swipeGestureLeft release];
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeGesture];
MyGestureDelegate *deleg = [[MyGestureDelegate alloc] init];
[swipeGesture setDelegate:deleg];
[swipeGesture release];
Handling Multiple GestureRecognizers
The UIGestureRecognizerDelegate
has a special function managing simultaneous recognition of several gestures on the same object, that will do the trick.
1) Set your UIViewController
to conform UIGestureRecognizerDelegate
2) Implement the following function:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if (gestureRecognizer == mainScene.panRecognizer || gestureRecognizer == mainScene.pinchRecognizer) && otherGestureRecognizer == mainScene.tapRecognizer {
return true
}
return false
}
In this particular example we allow the tap gesture to get triggered simultaneously with panning and pinching.
3) Then just assign the delegates to the pan and pinch gesture recognizers:
override func viewDidLoad() {
// your code...
// Set gesture recognizers delegates
mainScene.panRecognizer.delegate = self
mainScene.pinchRecognizer.delegate = self
}
How to detect the end of simultaneous gestures? (iOS)
How about a simple solution like counting gestures that are currently being handled, and acting when all of them end?
.h file:
int handledGesturesCount;
.m file:
- (id)init {
(...)
handledGesturesCount = 0;
}
// gesture handlers - the code for -pinch: repeats for -pan: and -rotate:
- (void)pinch:(UIPinchGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
handledGesturesCount += 1;
} else if (recognizer.state == UIGestureRecognizerStateEnded ||
recognizer.state == UIGestureRecognizerStateCancelled ||
recognizer.state == UIGestureRecognizerStateFailed)
{
handledGesturesCount -= 1;
if (handledGesturesCount == 0) {
[self resetImage];
}
}
}
- (void)pan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
handledGesturesCount += 1;
} else if (recognizer.state == UIGestureRecognizerStateEnded ||
recognizer.state == UIGestureRecognizerStateCancelled ||
recognizer.state == UIGestureRecognizerStateFailed)
{
handledGesturesCount -= 1;
if (handledGesturesCount == 0) {
[self resetImage];
}
}
}
- (void)rotate:(UIRotationGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
handledGesturesCount += 1;
} else if (recognizer.state == UIGestureRecognizerStateEnded ||
recognizer.state == UIGestureRecognizerStateCancelled ||
recognizer.state == UIGestureRecognizerStateFailed)
{
handledGesturesCount -= 1;
if (handledGesturesCount == 0) {
[self resetImage];
}
}
}
iOS: recognize pinch gestures but not two finger pans?
Have you try like this
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if ((gestureRecognizer is UIPinchGestureRecognizer || gestureRecognizer is UIPanGestureRecognizer)
&& (otherGestureRecognizer is UIPinchGestureRecognizer || otherGestureRecognizer is UIPanGestureRecognizer)) {
return false
}
return true
}
How to recognise gestures on pop-up view without interrupting gesture recognition on the view underneath?
After two days' work I found a very simple answer. I hope it helps someone. In the initialisation of the pop-up view, simply add the gesture recogniser to the superview, or any full-screen view, rather than the pop-up's own view. The target can still be the pop-up view:
self.recognizer = [[MyGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[fullscreenView addGestureRecognizer:self.recognizer];
And then disable user interaction:
self.userInteractionEnabled = NO;
This doesn't affect the gesture on the pop-up view, and the gestures associated with views underneath the pop-up now work fine too. If they compete with each other then the overrides in lorenzoliveto's answer can sort that.
ios recognizing gestures simultaneously with object handling
If you set your view controller to be the delegate of your gestures, you can implement:
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
I'm not sure if you're also trying to have the view handle touch events separately, but if you are, I'd recommend subclassing UIGestureRecognizer and handle touch events there.
Related Topics
Distinction Between Private and Fileprivate Top-Level Classes
Multiple Bottom Sheets - the Content Doesn't Load Swiftui
Create Codable Struct with Generic Type
How to Validate Dynamically Added Textfields on a Button Click in Swiftui
How to Use Keywords as Parameter Names in Swift
Coreplot with Swift: There Is No Yaxis.Majorintervallength
How to Retrieve a Random Object from Firebase Using a Sequential Id
Swift Parsing Attribute Name for Given Elementname
Uiscrollview with Embedded Uiimageview; How to Get the Image to Fill the Screen
Does Swift Guarantee the Storage Order of Fields in Classes and Structs
Does Swift Have a Null Coalescing Operator and If Not, What Is an Example of a Custom Operator
Swift Arrays and Contains, How to Determine If a Collection Contains an Object or Value
Swiftui Call Function on Variable Change
How to Convert a String to a Cstring in the Swift Language
Create Nsmanagedobject Subclass... Make a New Error in My Project
Swift 3: Convert a Null-Terminated Unsafepointer<Uint8> to a String