如何禁用superview touchBegan事件

时间:2015-01-26 08:20:37

标签: ios objective-c cocoa-touch

我有一个UIView子类,它所要做的就是:

@implement MyView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesBegan:touches withEvent:event];
    NSLog(@"touch began");
}
@end

现在我创建两个MyView实例,一个(C)高度为50px,另一个(S)高度为100px。较短的一个(C)是较高的(S)的子视图,它们具有不同的背景颜色。

然后我运行App,然后点击C,C和S都接收touchesBegan事件。

我的问题是,当我点击C时,如何阻止S(超级视图)接收触摸事件?当C高于它时(如果C是UIButton的一个实例,它按预期工作)。

对于下图:

  • 当我点击红色视图时,蓝色视图和红色视图都会收到事件,但我只希望红色视图接收它。
  • 当我点击蓝色区域时,只有蓝色视图接收事件,它按预期工作。

enter image description here

----编辑1 ----

此方法仅在我仅使用MyView时有效,它不会阻止事件传播:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesBegan:touches withEvent:event];
    UITouch *touch = [touches anyObject];
    if(touch.view != self){
        // ignore the event
        return;
    }
    NSLog(@"touch began");
}

----编辑2 ----

请参阅@ TomasCamin的评论

5 个答案:

答案 0 :(得分:0)

//your (S) view code
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
  UITouch *touch = [touches anyObject];
  CGPoint location = [touch locationInView:self];
  if (CGRectContainsPoint(yourCView.frame,location))
    return;
}

答案 1 :(得分:0)

您是否尝试过UIView.exclusiveTouch

修改:好的,正如我读到的UIView.exclusiveTouch一样,它只会在用户开始触摸给定视图后禁用视图框外其他视图的触摸。

如果点位于子视图内,请尝试覆盖pointInside:withEvent:以返回No。如果您返回touchesBegan:withEvent:,则不应触发No

编辑2 :没关系,这也行不通,因为它也会阻止子视图接收触摸。可能你真的应该只在主题超出子视图时调用超级:

if (self.subviews.count != 0) { // some naive implementation
    [super touchesBegan:touches withEvent:event];
}
NSLog(@"touch began");

或者,您可以描述您尝试解决的实际问题,也许有更好的解决方案。

答案 2 :(得分:0)

您可以在每个视图中使用不同的标记,然后您可以使用标记检查触摸的视图。

 - (void)viewDidLoad {
[super viewDidLoad];
  UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(10, 20, 300, 100)];
myView.tag = 100;
myView.backgroundColor = [UIColor blueColor];
[self.view addSubview:myView]; 

}

   -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *toucheObject = [touches anyObject];
if (toucheObject.view.tag == 100) {
    // your code
    NSLog("Your Object Touche");
}

}

答案 3 :(得分:0)

您可能会在[super touchesBegan:touches withEvent:event];内拨打[MyView touchBegan:withEvent],因为我无法复制您正在报告的问题。

如果它符合您的需要,我宁愿使用UIGestureRecognizer

例如,如果您尝试仅拦截一个点击,请使用UITapGestureRecognizer子类:

@implementation View

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
        [self addGestureRecognizer:tap];
    }

    return self;
}

- (void)tapped:(UIGestureRecognizer *)gesture {
    NSLog(@"MyView tapped %p", self);
}

@end

答案 4 :(得分:0)

您需要做的就是删除

 [super touches began:....]

//可能来自其他3个触摸事件 - 已移动:已结束:已取消:

你会得到你想要的东西。默认实现(通过将事件传递给超类来调用)是导致事件继续响应响应者链(到superview)的原因