2011-05-19 89 views
4

标题是很难的。 的主要情况是这样的UIGestureRecognizer子视图识别问题

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,你会发现,当你点击的区域(0,0,200,200)点击手势将生效,如果单击点(-150,-150 )轻拍手势不会生效。

我不知道上海华界外的点击是否会导致此问题或没有。

任何人有任何想法如何解决这一问题?

回答

2

我发现对于情况一样,唯一的解决方法是创建一个观点,即是透明的触摸作为主视图的一个实例。在这种情况下,内部视图将响应触摸,因为它符合主界面。 - 所有的触摸视图最终 完全可见:在课堂上,我从网上我可以控制的“触摸知名度”的水平,像这样发现不同的例子做。 只有子视图 - 视图本身不可见,但子视图触摸。 完全隐形 - 漂亮的自我解释我认为:)

我没有尝试使用它与手势识别器,但我不认为会有任何问题,因为它与常规触摸完美的作品。

代码很简单...

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 

我相信你可以将它容纳您的需求。

11

为了让子视图躺在上海华以外的响应触摸,覆盖上海华盈的hitTest:withEvent:

Documentation on Event Delivery

触摸事件。窗口对象使用命中测试和响应链,找到视图接收触摸事件。在命中测试中,窗口在视图层次结构的最顶层视图上调用hitTest:withEvent:这种方法进行的递归调用pointInside:withEvent:方法在返回YES,继续向下的层次结构,直到它找到它的边界内的触摸发生的子视图视图层次的每个视图。这一观点成为命中测试的观点。

  1. 创建的UIView的子类。
  2. 覆盖则hitTest:withEvent。
  3. 使用此UIView子类为上海华。下面

Add方法在子类:

(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]; 
} 

注:因为子视图使用反向枚举从后到前订购,我们希望先测试最前视图。

+0

工程太棒了!谢谢! – 2013-03-24 23:51:48