简体   繁体   English

当视图移动到超级视图之外时,touchesBegan停止工作

[英]touchesBegan stops working when view is moved outside its superview

I'm using [aSubview touchesBegan] to move aSubview 's position around on a screen in relation to its superview. 我正在使用[aSubview touchesBegan]在屏幕上移动一个aSubview的位置。 Its superview is not much larger than the subview itself. 它的超级视图并不比子视图本身大。 This is quite straightforward to do as the following snippet shows: 这很简单,如下面的代码段所示:

    UITouch* touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:[self superview]];
    self.center = touchPoint;

However once a aSubview is moved, as soon as any portion of it falls outside the bounds of its superview, touches in that section no longer register. 但是,一旦aSubview移动,只要它的任何部分超出其超级视图的范围,该部分中的触摸就不再注册。 In other words, touchesBegan no longer fire. 换句话说, touchesBegan不再开火。 I want touches in aSubview to register no matter where it's moved in relation to its superview. 我希望在子aSubview触摸无论它在哪里移动与其超级视图有关。

Any thoughts? 有什么想法吗?
Howard 霍华德

mcpunky's answer is almost good, except you can NOT make pointInside function to always return YES. mcpunky的答案几乎是好的,除了你不能pointInside函数总是返回YES。 This way the view will intercept all touches. 这样,视图将拦截所有触摸。

Instead, one needs to do more fine check: 相反,需要做更多的检查:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{

    return CGRectContainsPoint(self.subviewOutsideMe.frame, point) || CGRectContainsPoint(self.bounds, point);

}

I just had this problem with subviews not receiving input because the superview was simply not sending touch events for subviews that are outside it's bounds. 我只是遇到了这个问题,子视图没有收到输入,因为superview根本就没有为超出界限的子视图发送触摸事件。 Also, it was crucial to keep the bounds of the superview as they were and moving subviews up the hierarchy also wasn't feasible. 此外,保持超视图的界限至关重要,并且将子视图移动到层次结构中也是不可行的。 What did the job for me was overriding superview's 对我来说,这项工作取代了超级视图

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 

to always return YES. 总是返回YES。 Result: pretty much nothing changed in superview, nor the subviews, but input is received outside superview's boundaries. 结果:在superview和subviews中几乎没有任何变化,但输入是在superview的边界之外接收的。

I've talked to an Apple engineer about this. 我和一位苹果工程师谈过此事。 touchesBegan won't work in the portion of a subview that's not contained w/in its superview because the system clips each subview on the way down the hierarchy as it tries to determine which subview's touchesBegan gets called. touchesBegan将无法在其超级视图中未包含的子视图部分中工作,因为系统会在层次结构的路上剪切每个子视图,因为它会尝试确定调用哪个子视图的touchesBegan

In order to resolve the issue, I removed the intermediate wrapper views that were causing the clipping problem and hoisted the subviews up one level. 为了解决这个问题,我删除了导致剪辑问题的中间包装器视图,并将子视图提升了一个级别。 This necessitated a minor change in logic but ultimately proved to be a cleaner solution -- and more importantly, one that worked. 这需要对逻辑进行微小的改变,但最终证明是一个更清洁的解决方案 - 更重要的是,它是有效的。

I'm unsure if this is the correct way, but it's certainly one way. 我不确定这是否是正确的方法,但它肯定是一种方式。

Listen to the touchesBegan even in your parent object. 即使在您的父对象中也可以收听touchesBegan。 If you get an event, pass it onto the childs view by calling its touchesBegan yourself. 如果您收到一个事件,请通过自己调用touchesBegan将其传递给childs视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM