Re: Intercepting events and touches in UIPickerView subclasses? (or, WTF is going in the UIPickerView's responder chain?)
Re: Intercepting events and touches in UIPickerView subclasses? (or, WTF is going in the UIPickerView's responder chain?)
- Subject: Re: Intercepting events and touches in UIPickerView subclasses? (or, WTF is going in the UIPickerView's responder chain?)
- From: glenn andreas <email@hidden>
- Date: Fri, 18 Dec 2009 09:32:50 -0600
On Dec 18, 2009, at 6:00 AM, Sam Krishna wrote:
> Hi all,
>
> So, I'm working on a client project where he wants to have ActionOne for flicks on the UIPickerView and ActionTwo for non-flick selections.
>
> When I subclass UIPIckerView, I explicitly follow the pattern of overriding one of the standard methods for doing this kind of thing, and has worked *very well* in the past:
>
> - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
>
> Unfortunately, this method *never fires* in the UIPickerView's responder chain (I suspect it has something to do with the highly-animated nature of UIPickerView). The only methods I can get to fire to give me anything about CGPoint information are:
>
> - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
> - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
>
> what's interesting about these two methods is that they don't have any UITouch history with them. Sooo.... they are *mostly useless* also.
>
Like a number of built in classes, UIPickerView is composed of a number of subviews which actually do the "interesting stuff" (not unlike the way a UIButton has a UILabel and UIImageView to actually draw a button). As a result, it doesn't do anything, and overriding its touchesXXX methods doesn't do anything useful (since there's probably a scroll view like subview that's actually handling the events).
> I've considered applying a UIView on top of the Picker View to intercept the touches and make gesture determinations, since that works very well. But before I go down that road, I thought I'd ask the community what your thoughts are about solving this problem. Again, all I need is for touchesEnded:withEvent: to fire in the responder chain to get what I need.
>
Putting a view on top of a built in view works well for doing things like adding things to the appearance of the object, but can be very problematic, since in order for your approach to work, you'll need to forward the events to the real UIPickerView, and forwarding events is extremely problematic.
>From the documentation (iPhone Application Programming Guide > Event Handling > Touch Events > Handling Multi-Touch Events > Forwarding Touch Events):
Forwarding Touch Events
Event forwarding is a technique used by some applications. You forward touch events by invoking the event-handling methods of another responder object. Although this can be an effective technique, you should use it with caution. The classes of the UIKit framework are not designed to receive touches that are not bound to them; in programmatic terms, this means that the view property of the UITouch object must hold a reference to the framework object in order for the touch to be handled. If you want to conditionally forward touches to other responders in your application, all of these responders should be instances of your own subclasses of UIView.
So there are two solutions:
1) Roll your own UIPickerView implementation - surprisingly, not that difficult in many cases. Basically make a UIScrollView (or your own subclass so you can examine the touch events), put a bezel image on top of it, and have each row be a subview inside the scroll view. You'll need some work to handle things like reusing the row cells (since you probably don't want to create a scrolling view with hundreds of subviews).
2) Subclass UIApplication and override sendEvent: - this can get ugly from an architecture point of view (since you no longer have a nice little reusable view - you've got to do major surgery on the application itself), and sendEvent: does a whole lot of work that you'll want to be careful not to break.
Glenn Andreas email@hidden
The most merciful thing in the world ... is the inability of the human mind to correlate all its contents - HPL
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden