(IOS) RESPONSE event transfer, nextResponder Research

Source: Internet
Author: User

(IOS) RESPONSE event transfer, nextResponder Research
RESPONSE event transfer, nextResponder Research

Here, we will consider the following two cases.

 

Question 1. How do I call the methods in the controller of the parent view?

The answer is as follows:
[[Self superview]. nextResponder Method];
[[Self superview] nextResponder] Method];
[Self. nextResponder method];
The above can all be used according to the situation. It is best to judge when using it.

Official explanation
UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn' t ); UIViewController implements the method by returning its view's superview; UIWindow returns the application object, and UIApplication returns nil.

The following code can be used for judgment:

Id next = [self nextResponder];
While (! [Next isKindOfClass: [ViewController class]) // you cannot skip this step...Some people say that this cannot be jumped out, because it does not have the current view into ViewController, it naturally does not jump out, it will be an endless loop, you need to pay attention when using.
{
Next = [next nextResponder];
}
If ([next isKindOfClass: [ViewController class])
{
Controller = (ViewController *) next;
}


Question 2: When a subview needs to receive click events, and the parent view also needs to receive click events, what should I do?

Of course, you may call mysubview directly. you can do this by using superView, but sometimes the child view does not necessarily know the existence of this specific parent view, such as dynamically adding a child view.

Therefore, the message response chain pulling technology can be used here.

What we need to do below is to allow the sub-view to receive these events and upload them to the UIApplication. In the process of data transfer, if the Sub-view receives these events, the event will be terminated naturally. What we can do now is to allow the sub-view to receive events at the same time and prevent the event from being terminated, and continue to upload.

Extract some instructions:

"When a user interacts with the iPhone touch screen, the hardware detects physical contact and notifies the operating system. Then, the operating system creates an event and passes it to the event queue of the currently running application. The event is then passed to the priority object cyclically by the event. Priority response objects are the objects that interact with users when an event is triggered, such as button objects and view objects. If we write code to let the priority responder handle this type of event, it will process this type of event. After an event is processed, the responder has two options: 1. Discard it; 2. Pass it to the next responder in the response chain. The address of the next responder is stored in the nextResponder variable contained in the current responder object. If the priority responder cannot process an event, the event will be passed to the next responder until the event reaches the responder that can process it or the end of the response chain, that is, an object of the UIApplication type. After an event is received, an object of the UIApplication type is either processed or discarded."

For example, a view object has a button object. When you touch this button object, as the priority responder, this button object will receive an event. If this button object cannot process this event, it will be passed to the view object. If the view object cannot process this event, the event is passed to the View Controller object. And so on.

It should be noted that when we use the response chain, an event will not be automatically transmitted from a responder to the next responder. If you want to pass an event from a responder to the next responder, you must write the code."

Do the following:

ChildThe view code is as follows:

 

-(Void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event

{

// Here we can do what the sub-view wants to do. After the sub-view finishes, we can continue to upload the event so that the parent class or even the parent viewcontroller can get the event.

[[SelfnextResponder] touchesBegan: toucheswithEvent: event];

}

 

-(Void) touchesEnded :( NSSet *) touches withEvent :( UIEvent *) event

{

[[SelfnextResponder] touchesEnded: toucheswithEvent: event];

}

 

-(Void) touchesCancelled :( NSSet *) touches withEvent :( UIEvent *) event

{

[[SelfnextResponder] touchesCancelled: toucheswithEvent: event];

}

 

-(Void) touchesMoved :( NSSet *) touches withEvent :( UIEvent *) event

{

[[SelfnextResponder] touchesMoved: toucheswithEvent: event];

}

In addition, it should be noted that when you rewrite these methods, it is best to ensure that these methods are overwritten, otherwise the Event Response chain may become chaotic. This is my guess. I have not actually verified it.
1. responder object

In iOS systems, objects that can respond to and process events are called responder objects. UIResponder is the base class of all responder objects and defines various events in the UIResponder class, include Touch Events, Motion Events, and Remote-Control Events) the programming interface of is as follows:
-TouchesBegan: withEvent:
-TouchesMoved: withEvent:
-TouchesEnded: withEvent:
-TouchesCancelled: withEvent:
These four Methods Handle the touch start event, the Touch Move event, the touch stop event, and the touch trace cancel event respectively.

UIApplication, UIViewController, UIView, and all UIKit classes inherited from UIView (including UIWindow, inherited from UIView) are directly or indirectly inherited from UIResponder, so their instances are all responder object objects, all of the above four methods are implemented. The default implementation in UIResponder does nothing, but the direct subclass of UIResponder in UIKit (UIView, UIViewController ...) By default, the event is passed up along the responder chain to the next responder, that is, nextResponder. Therefore, when customizing the preceding event processing method of the UIView subclass, if you need to pass the event to next responder, you can directly call the corresponding event processing method of super, the corresponding method of super will pass the event to next responder, that is, use

[super touchesBegan:touches withEvent:event];

We do not recommend that you directly send messages to nextResponder, which may miss other processing of this event by the parent class.

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

 

In addition, when customizing the event processing method of the UIView subclass, if one of the methods does not call the corresponding method of super, other methods also need to be overwritten, without using the super method, otherwise, the event processing process will be messy.

NOTE: For the class hierarchy of the UIKit Framework, see UIKit Framework Reference.

Ii. responder chain

As mentioned above, the responder chain is a series of connected responder objects. Through the responder object, you can pass the responsibility for processing events to the next, more advanced object, that is, the nextResponder of the current responder object.
In iOS, the structure of the responder chain is:

  • The nextResponder attribute of UIView. If there is a UIViewController object that manages this view, this is the UIViewController object; otherwise, nextResponder is its superview.
  • The nextResponder attribute of UIViewController is its superview for managing views.
  • The nextResponder attribute of UIWindow is a UIApplication object.
  • The nextResponder attribute of UIApplication is nil.

    When processing an event, the iOS system uses the UIApplication object and the sendEvent of each UIWindow object to distribute the event to the responder object that handles the event (for a touch event, the event is hit-test view, other events are first responder). When the responder that handles this event does not process this event, you can use the responder chain to send it to the next level for processing.

    1. If hit-test view or first responder does not process this event, the event will be passed to its nextResponder for processing. If there is a UIViewController object, it will be passed to UIViewController and its superView.
    2. If viewController does not process the event, viewController transmits the event to its superView that manages the view.
    3. The top level of the view hierarchy is the UIWindow object. If the window still does not process this event, it is passed to the UIApplication.
    4. If the UIApplication object does not process this event, the event is discarded. Iii. Clever Use of nextResponder

      You can access the view object managed by UIViewController and all subviews of the view through the view attribute of UIViewController. However, there is no direct way to obtain the viewController for managing a view object, but we can indirectly obtain it using the responder chain. The Code is as follows:

      @implementation UIView (ParentController)-(UIViewController*)parentController{    UIResponder *responder = [self nextResponder];    while (responder) {if ([responder isKindOfClass:[UIViewController class]]) {return (UIViewController*)responder;}responder = [responder nextResponder];    }    return nil;}@end
      IOS event mechanism (I)

      DEC 7TH, 2013

      The premise of application is that the essence of understanding is understanding.

      This article describes how to learn and analyze events in iOS and their transmission mechanisms. In iOS, events are classified into three types:

      • Touch events (single point, multi-touch, and various gesture operations)
      • Sensor events (gravity, accelerometer, etc)
      • Remote Control event (Remote Control of iOS device multimedia playback, etc)

        These three types of events constitute a rich set of operation methods and user experience for iOS devices. This time, we will first learn and analyze the first type of events: Touch events.

        Gesture Recognizers

        Gesture Recognizers is a type of Gesture Recognition object that can be attached to a specified View and set a specified Gesture operation for it, such as clicking, sliding, or dragging. When a touch event occurs, the View with Gesture Recognizers configured first intercepts the touch event through the identification device. If the touch event is a touch listening event set for the View, then Gesture Recognizers will send the action message to the target processing object, and the target processing object will process the touch event. Let's take a look at the following flowchart.

        In iOS, View is the various UI controls we see on the screen. When a touch event occurs, Gesture Recognizers first obtains the specified event, then, an action message is sent to the target object, which is ViewController. In ViewController, the event is processed through the event method. Gesture Recognizers can be used to set events such as click, slide, and drag. With the Action-Target design mode, it can dynamically add various event listening for the View, instead of implementing a View subclass to complete these functions.

        In the above process, we usually set actions and targets in methods during development, such as setting listener events for UIButton.

        Common Gesture Recognition

        In the UIKit framework, the system has defined some common gesture identifiers for us in advance, including click, double-finger scaling, drag and drop, slide, rotation, and long press. With these gesture identifiers, we can construct a variety of operation methods.

        As shown in the preceding table, the UIKit framework provides six gesture identifiers, such as UITapGestureRecognizer. If you need to implement a custom gesture identifier, you can also inherit the UIGestureRecognizer class and override the method. We will not discuss it in detail here.

        Each Gesture Recognizer is associated with a View, but a View can be associated with multiple Gesture Recognizer because a View may respond to multiple touch operations. When a touch event occurs, Gesture Recognizer receives an action message before the View itself. The result is that Gesture Recognizer acts as a representative of the View to process touch events, or is called a proxy. When Gesture Recognizer receives a specified event, it sends an action message to the ViewController and processes it.

        Continuous and discontinuous actions

        A touch action can be divided into a continuous action and a discrete action. A continuous action, such as a sliding or dragging action, lasts for a short period of time. A discontinuous action, such as a click, it will be completed in an instant, and the processing of these two types of events is slightly different. For discontinuous actions, Gesture Recognizer only sends a single action message to ViewContoller. For continuous actions, Gesture Recognizer sends multiple action messages to ViewController, until all events are completed.

        There are two ways to add GestureRecognizer to a View: one is implemented through InterfaceBuilder, and the other is implemented through code. Let's see how it is implemented through code.

        MyViewContoller. m
        123456789101112131415
        -(Void) viewDidLoad {[super viewDidLoad]; // create and initialize the gesture object Pipeline * tapRecognizer = [[externalloc] initWithTarget: self action: @ selector (respondToTapGesture :)]; // specify the operation as one-click tapRecognizer. numberOfTapsRequired = 1; // Add GestureRecognizer [self. view addGestureRecognizer: tapRecognizer]; //...}

        Through the above Code, we have added a click event for the current View of MyViewController. First, we constructed the UITapGestureRecognizer object and specified the target as the current ViewController. action is the method implemented later, here we echo the Action-Target mode mentioned above.

        In the event processing process, the two methods are in different States. First, all touch events are initially in the available State (Possible), corresponding to the UIGestureRecognizerStatePossible class in the UIKit, if it is a discontinuous Action event, the state will only change from Possible to Recognized (Recognized, UIGestureRecognizerStateRecognized) or Failed (Failed, UIGestureRecognizerStateFailed ). For example, a successful click action corresponds to the Possible-Recognized process.

        If it is a continuous action event, if the event does not fail and the first action of the continuous action is successfully Recognized (Recognized), it is transferred from the Possible status to the Began (UIGestureRecognizerStateBegan) status, this indicates the start of the continuous action, and then changes to the Changed (UIGestureRecognizerStateChanged) State. In this state, the continuous action is continuously processed cyclically, after the action execution is completed, it changes to the Recognized State, and the action is in the completed state (UIGestureRecognizerStateEnded). In addition, the processing status of a continuous action event is Changed from Changed to Canceled (UIGestureRecognizerStateCancelled) because the identifier determines that the current action does not match the previously set event. When the status of each action changes, Gesture Recognizer sends an action message to the Target, that is, ViewController. It can process the action message accordingly. For example, a successful sliding gesture includes the process of pressing, moving, and lifting, corresponding to the Possible-Began-Changed-Recognized process.

        UITouch & UIEvent

        Every action Event on the screen is a Touch. In iOS, The UITouch object is used to represent each Touch. Multiple Touch forms an Event and the UIEvent is used to represent an Event object.

        In the above process, a double-finger scaling event is completed, and each finger status change corresponds to a phase in the event action processing process. The Touch action in the Began-Moved-Ended phase forms an Event ). There are corresponding methods in the Event Response object UIResponder to process the events in these stages respectively.

        • TouchesBegan: withEvent:
        • TouchesMoved: withEvent:
        • TouchesEnded: withEvent:
        • TouchesCancelled: withEvent:

          The following parameters correspond to the UITouchPhaseBegan, UITouchPhaseMoved, UITouchPhaseEnded, and UITouchPhaseCancelled classes. Used to indicate the status of different stages.

          Event Transfer

          For example, in iOS, the event is first transmitted from App (UIApplication), then to Window (UIWindow), and before being passed down to View, Window will hand over the event to GestureRecognizer, if GestureRecognizer identifies the passed event during this period, the event will not be passed to the View, but will be handed over to the Target (ViewController) for processing as we have previously said.

          Responder Chain)

          Generally, an iOS app usually has many UI controls on a screen, that is, there are many views. when an event occurs, how can we determine which View has responded to this event? Let's take a look.

          Responsder Object)

          The responder object is an object that can respond to and process events. UIResponder is the parent class of all responder objects, including UIApplication, UIView, and UIViewController. This means that all views and ViewController are responder objects.

          First Responder)

          The First Responder is the First View object to receive events. When we draw a View in Xcode Interface Builder, we can see that there is First Responder in the View structure.

          The First Responder here is the UIApplication. In addition, we can control a View to make it First Responder. By implementing the canBecomeFirstResponder method and returning YES, we can make the current View the First Responder, or call the becomeFirstResponder method of the View, for example, when UITextField calls this method, a keyboard is displayed for input. The input box control is the first responder.

          Event Transfer Mechanism

          As mentioned above, if the hit-test view cannot process the current event, the event will be transmitted along the Responder Chain, responsder Object ). Let's take a look at the event transfer mechanism in two different cases.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.