SubView UIGestureRecognizer recognition problem

The name is complicated. The main case is this:

UIView *superView = [[UIView alloc] initWithFrame:CGRectMake(0,0,400,400)]; UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(-200,-200,400,400)]; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]; [subView addGestureRecognizer:tapGesture]; [superView addSubView:subView]; 

OK, you will find that the touch gesture will work when you press the area at (0,0,200,200), if you press the point (-150, -150), the touch gesture will not take effect.

I do not know if a click outside the supervisor can cause this problem or not.

Does anyone know how to fix this?

+4
source share
2 answers

The only workaround I found for such a case is to create an instance of the view transparent to the strokes as the main view. In this case, the internal view will respond to touch, as it approaches the boundaries of the main one. In the class that I made from various examples found on the network, I can control the level of “touch visibility” as follows: fully visible - all strokes fall into view. only subviews - the view itself is invisible, but subviews get their touch. completely invisible - pretty self explanatory, i think :)

I have not tried to use it with gesture recognizers, but I don’t think there will be any problem, since it works fine with regular touches.

The code is simple ...

TransparentTouchView.h

 #import <UIKit/UIKit.h> typedef enum{ TransparencyTypeNone = 0, //act like usual uiview TransparencyTypeContent, //only content get touches TransparencyTypeFull //fully transparent for touches }TransparencyType; @interface TransparentTouchView : UIView { TransparencyType _transparencyType; } @property(nonatomic,assign)TransparencyType transparencyType; @end 

TransparentTouchView.m

 #import "TransparentTouchView.h" @implementation TransparentTouchView @synthesize transparencyType = _transparencyType; - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor clearColor]; } return self; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // UIView will be "transparent" for touch events if we return NO switch (_transparencyType) { case TransparencyTypeContent: for(UIView* subview in self.subviews){ CGPoint p = [subview convertPoint:point fromView:self]; if([subview pointInside:p withEvent:event]){ return YES; } } return NO; break; case TransparencyTypeFull: return NO; default: break; } return YES; } @end 

I believe that you can adapt it to your needs.

+2
source

To allow subviews outside the supervisor to respond to touch, override hitTest:withEvent: supervision.

Event Delivery Documentation

Touch events. The window object uses shock testing and a chain of responders to find a representation for receiving a touch event. In hit-testing, a window calls hitTest: withEvent: at the top of the view hierarchy; this method comes from a recursive call to pointInside: withEvent: on each view in the view hierarchy, which returns YES, walking down the hierarchy until it finds a subview within which the touch occurred. This performance becomes a hit test.

  • Subclass UIView.
  • Override hitTest: withEvent.
  • Use this subclass of UIView for the supervisor.

Add the method below to the subclass:

 (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator]; UIView *iSubView; while ((iSubView = [reverseE nextObject])) { UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event]; if(viewWasHit) { return viewWasHit; } } return [super hitTest:point withEvent:event]; } 

Note. . The reversible counter used from the moment when the nested objects are ordered by the front, and we want to check the appearance first.

+11
source

All Articles