iphone/ipad - parent UIView is blocking touches from getting to subviews - why?
Solution 1
Had to do with the frame of the parent view. If the frame doesn't enclose the subviews they won't receive touches.
Solution 2
UIView touches do not get passed to subviews if they lie outside of the superview's bounds as mentioned by the solution.
However if you want these subviews to respond to touch, override hitTest:withEvent:
of the superview.
Documentation on Event Delivery
Touch events. 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.
- Create a subclass of UIView (or other UIView subclass).
- Override hitTest:withEvent.
- Use this UIView subclass as the superview, so subview can respond to touches.
Add method below in subclass:
(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator];
UIView *iSubView;
while ((iSubView = [reverseE nextObject])) {
UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event];
if(viewWasHit) {
return viewWasHit;
}
}
return [super hitTest:point withEvent:event];
}
Note: Reverse enumerator used since subviews are ordered from back to front and we want to test the front most view first.
sol
Updated on June 18, 2022Comments
-
sol almost 2 years
I have a UIView which has a bunch of subviews. The subviews should be able to receive touch events, but for some reason the parent UIView takes the touch and does not pass it on. I have created it in a very standard way like I always create views:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,1024,768)]; self.mainView = myView; [myView release]; [self.view addSubview:self.mainView];
Then I create subviews and add them as normal:
[self.mainView addSubview:someOtherView];
I know self.mainView is getting the touch events when I listen in the main UIWindow:
VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768);
But why in the world can I not get the subviews to receive touches? I don't understand why this happens sometimes. I am not changing any default properties of mainView.
-
sol over 13 yearsI don't have any touch handlers. The subviews just are not responding to touches. For example a GestureRecognizer on one of the subviews doesn't work.
-
MOK9 over 11 yearsalso keep in mind to reference the 'bounds' of your parent view when positioning your subviews on screen. Your frame may or may not be the actual position on the screen.
-
Montana Burr over 8 years@sol: How do you know if that's the case?