views:

76

answers:

3

I have a UIViewController and an associated with it UIView. The UIView has a number of subviews.

How to handle touch event inside a specified rectangle in my UIViewController subclass?

This handling should be transparent: UIView and its subviews should still receive their touch events even if they intersect with the specified rectangle.

P.S.

  1. Overriding touchesBegan in the view controller doesn't work. Inner views doesn't pass events through.
  2. Adding a custom button to the end of UIView subviews list also doesn't work. Inner subviews doesn't receive touch events.
A: 

touchesBegan/touchesMoved/touchesEnded is probably the way to go. Depending on exactly what you are trying to do, UIGestureRecognizer may also be an option.

To make sure subviews pass events up, set userInteractionEnabled to YES on the subviews.

UIView sets this to YES by default, but some subclasses (notably UILabel) override this and set it to NO.

William Jockusch
can a UILabel have subviews? Or is this just to make sure it doesn't cover something behind it?
jasongetsdown
I've never done it, but I don't see any reason a UILabel couldn't have subviews. As for the reason . . . who knows? Usually one doesn't think of a label as something that receives a touch event, but sometimes it is convenient.
William Jockusch
A: 

Just because the views don't pass events through by default doesn't necessarily mean that's the way it has to be.

You could subclass the views that you are using and have them pass the events onto the view controller.

Another idea is to literally have a transparent handler on top of all of your views. That is, have a transparent UIView that sits above your views, handling touch events but also passing them through. I have no idea if this works in practice, but it sounds like it would.

David Liu
A: 

Your views, and their controllers can handle a touch using touchesBegan, touchesEnded or touchesMoved. Within touchesBegan as an example you can then choose to pass the event to the next responder in the responder chain. This way each of your views will get a chance to do something based on the touch event.

`- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

//do something here and then pass the event on

[self.nextResponder touchesBegan:touches withEvent:event];

} `

k.a