If I were rewriting UIKit, how would I implement UIControl?
I've been having some trouble fitting UIControl into my conceptual understanding of touch handling & the responder chain. Specifically, I'm confused about who is responsible for calling UIControl's begin
, continue
and endTrackingWithTouch:withEvent
calls.
My naive interpretation would be that UIControl is responsible for handling touch events like any other subclass of UIResponder, in touchesBegan:
and associated methods. This would get complicated, however, since a touch event remains associated with the view that first handles it, and this would create a situation where a touch that originated on a button but continued as a pan across the screen would continue being handled by that button, which seems counter-intuitive. I could imagine that the button could begin forwarding those touch events to its superview in this case, but that seems ugly. This also all gets slightly confusing because of the UIControlEvents, such as touchUpInside, which suggest that touches are being processed elsewhere and the UIControl is only being notified of discreet events.
My best guess, here, is that UIControls are handled differently when the view-heirarchy is being walked to find a responder, and that the topmost non-control responder checks of any of its subviews are UIControls, and then calls the correct methods as required, but this also seems a little strange.
Does anybody have any guidance or clarification on this point? I've dug through the documentation a bit but haven't found anything explicit.
UIControl
is a subclass of UIView, so it can detects users interactions and it uses the target-action pattern to invoke some methods/actions on objects/targets.
As you said, in Apple way : "An Event Travels Along a Specific Path Looking for an Object to Handle It"
So the basic workflow for UIControl
:
UIControl
detects basic events ( UIControlEventTouchDown
, UIControlEventTouchCancel
...), the event is handled by the chain Responder workflow.
addTarget:action:forControlEvents:
tells a UIControl
to invoke the action on the target for the event type argument.
When the eventType and the target will match, the action will be fire.
EDIT
UIControl
is just an interface to provide target/action pattern behavior to the objects that implements it.
So what's really happen is that when you touch the screen, there is a basic UIEvent that is created with a timestamp, a type (Touches, Motion or RemoteControl), and a subtype.
iOS will collect into this event all UITouch
related to this event ( one UITouch
= one finger touch action) . A UITouch contains the UIView
and the UIWindow
where the touch occur and other stuffs.
There are three functions in UIEvent :
allTouches()
: That returns a NSSet
of UITouch
touchesForView(aView)
: That returns a NSSet
of UITouch
for a specific UIView
touchesForWindow(aWindow)
: That returns a NSSet
of UITouch
for a specific UIWindow
From my understanding, when the Event is fired, the system will send it to your UIApplication
, and it will send the event to the FirstResponderChain workflow.
So, I think that when is going down in the View Hierarchy, it checks if the touchesForView
method returns something, if it's return something then it call the appropriate method on the UIView
that implements UIResponder
), so it can call touchesBegan:withEvent:
for example. Else it keeps going.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.