Passing touch events to appropriate sibling UIViews
I’m trying to handle touch events with
touchesBegan in an overlay to a parent
UIView but also allow the touch input to pass through to sibling
UIViews underneath. I expected there would be some straight-forward way to process a touch event and then say “now send it to the next responder as if this one didn’t exist”, but all I can find is the
nextResponder method which appears to be giving back the parent to my overlay view. That parent is then not really passing it onto the next sibling of that overlay view so I’m stuck uncertain how to do what seems like a simple task that is usually accomplished with a touch callback that gets a True or False return value to tell it whether to keep processing down the widget hierarchy.
Am I missing something obvious?
2 Solutions Collect From Internet About “Passing touch events to appropriate sibling UIViews”
Late answer, but I think you would be better off overriding
hitTest:withEvent: instead of
touchesBegan. It seems to me that
touchesBegan is a pretty “high-level” method that is there to just do a simple thing, so you cannot alter at that level if the event if propagated further. The right place to do that is
Also have a look at this S.O. answer for more details about this point.
I understand the desired behavior you’re looking for Joey – I haven’t found something in the API that supports this automatic messaging-up-the-chain behavior with sibling views.
What I originally wrote below was with respect to just informing a parent UIView about a touch. This still applies, but I believe you need to take it a step further and have the parent UIView use the hit testing technique that Sergio described on each of it’s subviews that are siblings to the overlay, and have the parent UIView manually invoke a “do something” method on each of it’s subviews that pass the hit test. Each of those sibling views can return a BOOL value on whether to abort informing other siblings or continue the chain.
If you find yourself using this pattern a lot, consider adding a category method on UIView that encapsulates the hit testing and asking views to perform a selector.
My Original Answer
With a little bit of manual work, you can wire this together yourself. I’ve had to do this, and it worked for me, because I had an oft-repeated use case (an overlay view on a button), where it made sense to create some custom classes. If your situation is similar, one of these techniques will suffice.
If the overlay doesn’t need to do anything but look pretty, have it opt out of touch handling completely with
userInteractionEnabled = NO. This will make it so that the touch event goes to it’s parent UIView (the one it is an overlay to).
Have the overlay absorb the touch event (as it would by default), and then invoke a method on the parent UIView indicating that a touch or certain gesture was recognized, and here’s what it is. This way, the UIView behind the overlay still gets to act on the touch recognition, even if someone else did the interception.
With Option 2, it’s more a fit for simple
UIControlEvent types, like
UIControlEventTouchUpInside. In my case (a custom
UIButton subclass with a custom overlay view on top of it), I’ll wire touch down and touch up events on the button to two separate methods. These fire if a touch down or touch up inside event occurs on the button itself. But, they are also hooks I can invoke from the overlay view if I need to simulate that a button press occurred.
Depending on your needs, you could have a known protocol between the overlay and it’s parent UIView or just have the overlay test the UIView informally, with a
respondsToSelector: check before invoking
performSelector: on it with the custom method you want called that would have fired automatically if the UIView wasn’t covered by an overlay.
- Xcode 4 and BWToolKit
- Cast to different C struct unsafe pointer in Swift
- When should I use the “self” keyword?
- Cordova Phonegap IOS App Settings.Bundle Possible?
- This iPhone 6 is running iOS 10.1 (14B55c), which may not be supported by this version of Xcode
- NSMutableURLRequest timeout interval not taken into consideration for POST requests
- Xcode tableview how to select ONE row in EACH section
- Xcode : */swiftc failed with exit code 11, what can I do?
- How to keep UITableView contentoffset after calling -reloadData
- Fabric release XCode 6.3 codesign xcode-select
- How to decode the BLE advertisement data
- iOS Drawing text in the centre of shapes
- clang: error: no such file or directory: '/Users/waterskiingmithrill/Development/iPhone/Event/Event_Prefix.pch'
- new UIPDFPageRenderOperation error with iOS 9.3?
- Triangle UIView – Swift