I have a subclass of UIView
on top of a UITableView
. I am using the UITableView
to display some data and, at the same time, I would like to overlay an animation that follows the finger (for instance, leaving a trail).
If I get it right, I need the touch events to be handled both by the UIView
subclass and the UITableView
. How can I do that?
Is it possible to have, ie, touchesMoved
being triggered on the UIView subclass and then on UITableView
?
Thank you so much for any help.
The way I have solved this problem is in a way that is not that clean, but it works. Please let me know if there's a better way to do this.
I have overridden hitTest
for my custom UIView
so that it directs touches to the UITableView
underneath. Then in the UITableView
I am handling the gestures through touchesBegan
, touchesMoved
, etc. There I am also calling touchesBegan
on the UIView
.
In this way touches are handled by two views.
The reason why I am not doing the other way around (having UIView
's touchesBegan
calling UITableView
's touchesBegan
) is that gestures recognizers on the UITableView
would not work.
UIView
subclass' hitTest
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// tview is the UITableView subclass instance
CGPoint tViewHit = [tView convertPoint:point fromView:self];
if ([tView pointInside:tViewHit withEvent:event]) return tView;
return [super hitTest:point withEvent:event];
}
UITableView
subclass's touchesBegan
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:touch.view];
// ....
// view is the UIView's subclass instance
[view touchesBegan:touches withEvent:event];
}
No, you cann't do it implicity. Event Delivery chapter says
The window object uses hit-testing and the responder chain to find the
view to receive the touch event. In hit-testing, a window calls
hitTest:withEvent: on the top-most view of the view hierarchy; this
method proceeds by recursively calling pointInside:withEvent: on each
view in the view hierarchy that returns YES, proceeding down the
hierarchy until it finds the subview within whose bounds the touch
took place. That view becomes the hit-test view.
So, when window finds touched view it returns YES. Only one view can handle touches at the current moment.
But if you need to handle event for UITableView then handle it for UIView! You can convert touched point to required coordinates with – convertPoint, – convertRect functions, add subview to UITableView and move it depends on coordinate, and a lot of another things.
UITableView relays unhandled touch events to UIView. (Google "responder chain")
UITableView Documentation
So, you can handle your touch events in UIView only. So. In your UIView
touchesstart - do initialization stuff
touchesmove - draw tail on UIView (Use timers/delayedresponse to desable points so that it would look like a trail)
touchesend - do remaining stuff
Hope this helps.