I've been looking for a way to intercept all touch events of an app.
I saw that I can add a gesture recognizer to the main window and get all the touches by using it's delegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
NSLog(#"%#",touch);
return NO;
}
This way I don't harm all of the other touch events the app has.
The problem is that I cannot get swipe events and such this way. Moreover, I cannot override UIWindow sendEvents because my app is an outside framework.
I also do not want to add a transparent UIView on top.
Is there any other way to get swipes and other gesturs?
To intercept all touch events of an app, use a UIWindow subclass and override sendEvent:.... Every touch event passes through this bottleneck method. Be warned that you are now operating at a very low level and can easily break everything.
I managed to get this to work by using a custom gesture recognizer attached to the keyWindow and with using the method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Which also gives me all the touches and doesn't disturb any other recognizers.
If anyone know why I shouldn't be doing that, I'd be happy to hear about it.
Related
I am working with google maps iOS sdk 1.8.1 and I want to use UIScreenEdgePanGestureRecognizer from the left over the map. I already have the gesture working but I want to disable the scrolling on the map only when I am using the UIScreenEdgePanGestureRecognizer. I tried to disable the scroll in the action method of the gesture with
myMapView.settings.scrollGestures = NO;
and also in
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
but it didn't work as i believe the map is the one receiving first the event, so is there a way to detect first the UIScreenEdgePanGestureRecognizer before the google map gestures? I'll appreciate any suggestion.
If you implement on your delegate:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return NO;
}
You'll be able to disable multi-gesture recognition.
I've set...
self.navigationController.hidesBarsOnSwipe = YES;
I also have a UISlider in a tableHeaderView. The UISlider no longer slides when using hidesBarsOnSwipe. I assume hidesBarsOnSwipe is consuming the gesture that the slider would typically use. To get around this with traditional gesture recognizers you can use...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
to fire more than one gesture at a time. But to get that to work you need to set the delegate, and you are not allowed to change the barHideOnSwipeGestureRecognizer delegate.
Any ideas? I'm stumped. Not sure how to get past this.
I have a button on top of a GLKView.
When i click on the button, i also receive a long touch notification on the GLKView that is behind the button.
How can i prevent the notification from propagating to the view?
Found the solution to my question. The following code will do the trick:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
UIView* viewRceivingTouch = touch.view;
return (viewRceivingTouch == self.glkView);
}
I have a UIView which has a UIScrollView subview and is a UIScrollViewDelegate. Since I've implemented viewForZoomingInScrollView I stopped getting pan and pinch events for the UIView.
How can I get these events back?
Try adding a delegate to your gesture recognizer that implements
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
try:
[yourviewname setUserInteractionEnabled:YES];
Edit: I just re-read your question. Are you saying that you can't pan and/or pinch? Or are you saying that you aren't being notified when you pan and/or pinch?
I have a view with button and touch-move gesture. When user touches button it becomes selected and keeps receiving touch-move events. I want to deselect the button on touch-move and pass moves to gesture.
How to cancel touch receiving on button "elegantly"?
Try the next line of code on Swift 4
youButton.touchesCancelled([], with: nil)
Works well with pan gesture reco
You need to implement the UIGestureRecognizerDelegate. Specifically this method. Then just build your logic for deciding if the gesture should receive the touch or not. If you return NO then the touch is up for grabs for the button. if you return YES the gesture to take the touch.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
If you never even more control I think you'll need to subclass the button and takeover its hit testing.