简体   繁体   中英

How do Responder Chain Works in IPhone? What are the “next responders”?

This is what the documentation says:

If the first responder [to an event or action message] cannot handle an event or action message, it forwards it to the “next responder” in a linked series called the responder chain. The responder chain allows responder objects to transfer responsibility for handling an event or action message to other objects in the application.

If an object in the responder chain cannot handle the event or action, it resends the message to the next responder in the chain. The message travels up the chain, toward higher-level objects, until it is handled. If it isn't handled, the application discards it.

Okay, what is the next responder?

Is it the parent view? The view behind it? How does iOS decide what is the first responder and second responder?

The First Responder is a very specific concept in Cocoa. The only time iOS decides to set the First Responder is when a text field gets focus. At all other times you must explicitly control which object you want to be the first responder (see -canBecomeFirstResponder, -becomeFirstResponder).

There is no such thing as a second responder.

All responders have a NextResponder , (which can be nil). This means that starting from any responder there may be (but may not be) an arbitrarily length chain of responders ( responder -> nextResponder -> nextResponder -> etc ) along which events are passed until they are handled.

There is a default chain which can be view -> superview -> superview but might also include UIViewControllers, UIWindows, UIWindowControllers, UIApplication and more, so it heavily depends on your object hierarchy (not just your view hierarchy - so no, you can't say nextResponder is always the parent view). On OSX 10.6 the default chain is even different for different types of events and actions and can even include your app delegate, which may or may not be a responder, i'm not sure if this is the case in iOS tho.

The default chain is only the default tho, so after you have managed the First Responder it is down to you to insert, remove and append items to it's responder chain to achieve your desired aim.

The responder chain is quite important and complicated, you should take time to read the Apple docs about it.

From the docs for the nextResponder :

The UIResponder class does not store or set the next responder automatically, instead returning nil by default. Subclasses must override this method to set the next responder. 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.

Apps receive and handle events using responder objects.

A responder object is any instance of the UIResponder class,

  • common subclasses include

    UIView, UIViewController, and UIApplication .

Responders receive the raw event data and must either handle the event or forward it to another responder object.

When your app receives an event, UIKit automatically directs that event to the

  • most appropriate responder object, known as the

    first responder.

Unhandled events are passed from responder to responder in the active responder chain,

which is the dynamic configuration of your app's responder objects.

Now look at the below screen-shot, Also consider the View-Hierarchies from the front:

图像

UIbutton/UITextField --(nextResponder)-> UIView --(nextResponder)-> UIViewController

--(nextResponder)-> UIWindow --(nextResponder)-> UIApplication --(nextResponder)-> UIApplicationDelegate

That is how the Responder chain works on iOS, hope it will help anyone Also the latest article on Apple's website is --> Link (Very Well explained.)

The responder chain for any event is

UIView -> ViewController -> Window-> App Delegate

Run the below code for better understanding.

//
//  AppDelegate.swift
//  ResponderChain
//
//  Created by Ankit on 02/09/17.
//  Copyright © 2017 Ankit. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("App Delegate touch began")
    }


}



//
//  ViewController.swift
//  ResponderChain
//
//  Created by Ankit on 02/09/17.
//  Copyright © 2017 Ankit. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("ViewController touch Began")
        next?.touchesBegan(touches, with: event)
    }


}

extension UIWindow{
    open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("Window Touch Began")
        next?.touchesBegan(touches, with: event)
    }
}
extension UIView{
    open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("UIView touch Began")
        next?.touchesBegan(touches, with: event)
    }
}

The responder chain is a series of linked responder objects. It starts with the first responder and end with the app object. If the first responder cannot handle an event, it forwards the event to the next responder in the responder chain.

A responder object is an object that can respond to and handle events. The UIResponder class is the base class for all responder objects, and it defines the programmatic interface not only for event handling but also for common responder behavior. Instances of the UIApplication, UIViewController, and UIView classes are responders, which means that all views and most key controller objects are responders. Note that Core Animation layers are not responders.

The first responder is designated to receive events first. Typically, the first responder is a view object. An object becomes the first responder by doing two things:

Overriding the canBecomeFirstResponder method to return YES.

Receiving a becomeFirstResponder message. If necessary, an object can send itself this message.

refer Apple doc for more explanation.

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