iPhone 中的同级子视图不接收触摸
我有一个视图(parent
),它有两个子视图,一个在顶部(topChild
),另一个在另一个(bottomChild
)上。
如果我点击屏幕,则只有 topChild
和 parent
接收触摸事件。
我应该更改什么才能将触摸事件传播到 bottomChild
?
代码:
- (void)viewDidLoad
{
[super viewDidLoad];
MYView* parent = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
parent.tag = 3;
parent.backgroundColor = [UIColor redColor];
MYView* bottomChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
bottomChild.tag = 2;
bottomChild.backgroundColor = [UIColor blueColor];
[parent addSubview:bottomChild];
MYView* topChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
topChild.tag = 1;
topChild.backgroundColor = [UIColor greenColor];
[parent addSubview:topChild];
[self.view addSubview:parent];
}
其中MYView
是UIView
的子类,仅记录touchesBegan
。
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%d", self.tag);
[super touchesBegan:touches withEvent:event];
}
结果:
触摸绿色区域会产生以下日志:
TouchTest[25062:f803] 1
TouchTest[25062:f803] 3
我的第一个想法是使 parent
将所有 touchesSomething
调用传播到其子级,但(A)我怀疑可能有一个更简单的解决方案,(B)我不知道哪个孩子将事件发送给父母,并且发送touchesSomething
向同一个视图发送两次消息可能会导致恶作剧。
提出问题后,我发现这个 post 建议覆盖 hitTest< /code> 更改接收触摸的视图。我将尝试这种方法并更新问题(如果有效)。
I have a view (parent
) with two subviews, one on top (topChild
) of the other (bottomChild
).
If I tap on the screen only topChild
and parent
receive the touch event.
What should I change to propagate the touch event to bottomChild
as well?
The code:
- (void)viewDidLoad
{
[super viewDidLoad];
MYView* parent = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
parent.tag = 3;
parent.backgroundColor = [UIColor redColor];
MYView* bottomChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
bottomChild.tag = 2;
bottomChild.backgroundColor = [UIColor blueColor];
[parent addSubview:bottomChild];
MYView* topChild = [[MYView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
topChild.tag = 1;
topChild.backgroundColor = [UIColor greenColor];
[parent addSubview:topChild];
[self.view addSubview:parent];
}
Where MYView
is a subclass of UIView
that only logs touchesBegan
.
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%d", self.tag);
[super touchesBegan:touches withEvent:event];
}
The result:
Touching the green area produces the following log:
TouchTest[25062:f803] 1
TouchTest[25062:f803] 3
My first idea was to make parent
propagate all the touchesSomething
calls to its children but (A) I suspect there might be an easier solution and (B) I don't know which child sent the event to parent, and sending touchesSomething
messages twice to the same view might cause shenanigans.
After asking the question I've found this post that suggests to override hitTest
to change the view that receives the touches. I will try this approach and update the question if it works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个有趣的问题,最好通过重新思考事物的结构方式来解决。但要使其按照您建议的方式工作,您需要捕获当前顶视图中的触摸事件,将其传递给父视图,然后将其向下传播到父视图的所有子视图。要实现此功能,您需要 touchesBegan:(或用于拦截触摸的任何其他方法)在所有视图中不执行任何操作,仅在父视图调用的方法中执行操作。
这实际上是另一种说法,不处理视图中的触摸,捕获它们但通知父视图视图,然后根据需要调用子视图方法以产生您想要的效果。
请注意,我在该代码中将
super
更改为self.superview
。您可能也可能不想调用super
的方法,具体取决于您正在做什么,以及调用的位置可能位于parentNotifiedTouchesBegan
中。当然,您可以知道哪个子视图发送了事件,只需使用自定义方法通知超级视图,而不是调用其
touchesBegan:
。使用self
参数。It's an interesting problem you have that is probably something best addressed through a rethink of the way you have things structured. But to make it work the way you suggest you need to catch the touch event in the current top view, pass it to the parent and then propagate it down through all subviews of the parent view. To make this work you would need the
touchesBegan:
(or whatever other method you use to intercept the touch) to do nothing in all the views, doing the action only in the method called by the parent view.Which is really another way of saying don't handle touches in the views, catch them but notify the parent view view and then call subview methods as required to cause the effect you want.
Note I changed
super
toself.superview
in that code. You may or may not also want to callsuper
's method depending on what you are doing, and the place to call that may be inparentNotifiedTouchesBegan
.You can know which subView sent the event of course, just use a custom method to notify the superview instead of calling its
touchesBegan:
. Use aself
argument.如果您不需要触摸孩子,请设置
If you don't need the touches on the children then set