Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

touchesBegan stops working when view is moved outside its superview

Tags:

iphone

touch

I'm using [aSubview touchesBegan] to move aSubview's position around on a screen in relation to its superview. 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. In other words, touchesBegan no longer fire. I want touches in aSubview to register no matter where it's moved in relation to its superview.

Any thoughts?
Howard

like image 885
hkatz Avatar asked Dec 12 '10 17:12

hkatz


3 Answers

mcpunky's answer is almost good, except you can NOT make pointInside function to always return 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);

}
like image 170
Lukasz Avatar answered Nov 05 '22 08:11

Lukasz


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. 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. Result: pretty much nothing changed in superview, nor the subviews, but input is received outside superview's boundaries.

like image 34
mt_ Avatar answered Nov 05 '22 10:11

mt_


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.

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.

like image 24
hkatz Avatar answered Nov 05 '22 10:11

hkatz