简体   繁体   English

响应链如何在 iPhone 中工作? 什么是“下一个响应者”?

[英]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.如果响应者链中的 object 无法处理事件或动作,它会将消息重新发送给链中的下一个响应者。 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? iOS 如何决定什么是第一响应者和第二响应者?

The First Responder is a very specific concept in Cocoa. First Responder 是 Cocoa 中一个非常具体的概念。 The only time iOS decides to set the First Responder is when a text field gets focus. iOS 决定设置 First Responder 的唯一时间是文本字段获得焦点时。 At all other times you must explicitly control which object you want to be the first responder (see -canBecomeFirstResponder, -becomeFirstResponder).在所有其他时间,您必须明确控制您希望哪个 object 成为第一响应者(请参阅 -canBecomeFirstResponder、-becomeFirstResponder)。

There is no such thing as a second responder.没有第二响应者之类的东西。

All responders have a NextResponder , (which can be nil).所有响应者都有一个NextResponder ,(可以为零)。 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.这意味着从任何响应者开始,可能(但可能不是)任意长度的响应者链( responseer -> nextResponder -> nextResponder -> etc ),事件沿着这些链传递直到它们被处理。

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).有一个默认链可以是 view -> superview -> superview 但也可能包括UIViewControllers、UIWindows、UIWindowControllers、UIApplication等等,所以它在很大程度上取决于你的 object 层次结构(不仅仅是你的视图层次结构 - 所以不,你可以' t 说 nextResponder 始终是父视图)。 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.在 OSX 10.6 上,对于不同类型的事件和操作,默认链甚至不同,甚至可以包括您的应用程序委托,它可能是也可能不是响应者,我不确定 iOS 是否是这种情况。

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.默认链只是默认链,因此在您管理了 First Responder 之后,您可以在其响应者链中插入、删除和 append 项目以实现您想要的目标。

The responder chain is quite important and complicated, you should take time to read the Apple docs about it.响应者链非常重要且复杂,您应该花时间阅读有关它的 Apple 文档。

From the docs for the nextResponder :来自nextResponder的文档:

The UIResponder class does not store or set the next responder automatically, instead returning nil by default. UIResponder class 不会自动存储或设置下一个响应者,而是默认返回 nil。 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); UIView 通过返回管理它(如果有)或其上级视图(如果没有)的 UIViewController object 来实现此方法; UIViewController implements the method by returning its view's superview; UIViewController 通过返回其视图的父视图来实现该方法; UIWindow returns the application object, and UIApplication returns nil. UIWindow 返回应用程序 object,UIApplication 返回 nil。

Apps receive and handle events using responder objects.应用程序使用响应者对象接收和处理事件。

A responder object is any instance of the UIResponder class,响应者 object 是UIResponder class 的任何实例,

  • common subclasses include常见的子类包括

    UIView, UIViewController, and UIApplication . UIView、UIViewController 和 UIApplication

Responders receive the raw event data and must either handle the event or forward it to another responder object.响应者接收原始事件数据并且必须处理该事件或将其转发给另一个响应者 object。

When your app receives an event, UIKit automatically directs that event to the当您的应用收到事件时,UIKit 会自动将该事件定向到

  • most appropriate responder object, known as the最合适的响应者 object,称为

    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:现在看下面的屏幕截图,还要考虑前面的 View-Hierarchies:

图像

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

--(nextResponder)-> UIWindow --(nextResponder)-> UIApplication --(nextResponder)-> UIApplicationDelegate --(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.)这就是 Responder 链在 iOS 上的工作方式,希望它对任何人都有帮助 另外 Apple 网站上的最新文章是 --> 链接(很好解释。)

The responder chain for any event is任何事件的响应者链是

UIView -> ViewController -> Window-> App Delegate UIView -> ViewController -> 窗口-> 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.它从第一响应者开始,到应用程序 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.响应者 object 是可以响应和处理事件的 object。 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. UIResponder class 是所有响应者对象的基础 class,它不仅为事件处理定义了编程接口,还为常见的响应者行为定义了编程接口。 Instances of the UIApplication, UIViewController, and UIView classes are responders, which means that all views and most key controller objects are responders. UIApplication、UIViewController 和 UIView 类的实例是响应者,这意味着所有视图和大多数关键 controller 对象都是响应者。 Note that Core Animation layers are not responders.请注意,核心 Animation 层不是响应者。

The first responder is designated to receive events first.第一响应者被指定首先接收事件。 Typically, the first responder is a view object.通常,第一响应者是视图 object。 An object becomes the first responder by doing two things: object 通过做两件事成为第一响应者:

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.有关更多说明,请参阅 Apple 文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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