防止父视图在子视图作用后接收触摸事件

问题描述 投票:6回答:4

我在iOS应用程序上的事件响应者链中遇到麻烦。

问题如下,我在较大的视图(正方形)上有一组子视图(气泡),并且我希望能够在单击按钮时显示某个视图,但是如果我在其他任何位置单击,隐藏相同的视图。

问题是,当我点击气泡时,两个视图(子视图和父视图)都在触发,如何防止这种情况?

如果孩子已经在触摸事件上行动了,那不应该就此结束吗?

[我的泡泡通过UITapGestureRecognizer识别出Tap手势,而父视图(正方形)使用touchesBegan:方法

此图说明了我当前带有多个气泡的设置:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS8wdUhOai5wbmcifQ==” alt =“在此处输入图像描述”>

代码:

@implementation Bubble
...
-(id) initWithFrame: (CGRect) frame {
    UITapGestureRecognizer *singleFingerDTap = [[UITapGestureRecognizer alloc]
                                                initWithTarget:self action:@selector(handleSingleTap:)];
    singleFingerDTap.numberOfTapsRequired = 1;
    [self addGestureRecognizer:singleFingerDTap];

}

-(void) handleSingleTap {
NSLog(@"Bubble tapped, show the view");
}

用于Square

@implementation Square
...
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"square touched, lets hide the view");
}

轻按之后,我会在控制台上看到两个NSLogs

objective-c ios cocoa-touch uigesturerecognizer
4个回答
3
投票

我发现了问题所在。 UIView继承自UIResponder,触发触摸开始事件的视图将检测基本触摸事件。您在主视图中添加的子视图也响应touches begin方法。这非常基础。您还添加了带有点击手势识别器的选择器方法。因此,对气泡的任何触摸都会触发这两种方法,从而触发两个日志。尝试使用另一个选择器将另一个手势识别器添加到视图,例如

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tappedOnBubble)];
    [self.bubbleView addGestureRecognizer:tap];

UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tappedOnMainView)];
   [self.view addGestureRecognizer:tap2];


-(void)tappedOnMainView
{
    NSLog(@"touched on main View");
    [self.vwToShow setHidden:NO];
}
-(void)tappedOnView
{
    NSLog(@"tapped on bubbleview");
    [self.vwToShow setHidden:YES];
}

6
投票

嗯,这就是问题所在。 touchesBegan将获得所有触摸,包括手势识别器进行的触摸。您也可以尝试设置gestureRecognizer.cancelsTouchesInView = TRUE或将touchesBegan用作气泡。

由于您似乎在这里制作游戏,您是否正在使用像cocos2D这样的引擎?如果是这样,则可以使用更简单的方法来完成所需的操作。

希望这会有所帮助。

干杯!

编辑:

如果仅使用手势识别器,则触摸不会发送到层次结构中的下一个视图。我想这就是你想要的。如果您决定开始接触,我认为您应该做这样的事情:

//在气泡视图类中

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event 
{
    if(theTouchLocation is inside your bubble)
    {
        do something with the touch
    }
    else
    {
        //send the touch to the next view in the hierarchy ( your large view )
       [super touchesBegan:touches withEvent:event];
       [[self nextResponder] touchesBegan:touches withEvent:event];
    }
}

1
投票

执行此操作:

@implementation Square{

 ...
 -(id) initWithFrame: (CGRect) frame {
    UITapGestureRecognizer *singleFingerDTap = [[UITapGestureRecognizer alloc]
                                                initWithTarget:self action:@selector(handleSingleTap:)];
    singleFingerDTap.numberOfTapsRequired = 1;
    [self addGestureRecognizer:singleFingerDTap];

 }

 -(void) handleSingleTap {
   NSLog(@"Sqaure tapped, hide the view");
 }

}

0
投票

为什么也不要在主视图上使用轻击手势识别器?触摸开始就像编写自己的手势识别器一样,但是要困难得多。使用多个敲击识别器,只有一个会触发。


0
投票

将手势识别器添加到阻止儿童。

self.blockerView.addGestureRecognizer(UITapGestureRecognizer())
© www.soinside.com 2019 - 2024. All rights reserved.