简体   繁体   中英

How would you reimplement UIControl? How does it fit into the responder chain?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM