31

这就是文档所说的:

如果第一响应者 [对事件或动作消息] 无法处理事件或动作消息,它会将其转发给称为响应者链的链接系列中的“下一个响应者”。响应者链允许响应者对象将处理事件或动作消息的责任转移给应用程序中的其他对象。

如果响应者链中的对象无法处理事件或动作,它会将消息重新发送给链中的下一个响应者。消息沿着链向上传播,到达更高级别的对象,直到被处理。如果未处理,则应用程序将其丢弃。

好的,下一个响应者是什么?

是父视图吗?背后的风景?iOS 如何决定什么是第一响应者和第二响应者?

4

5 回答 5

33

First Responder 是 Cocoa 中一个非常具体的概念。iOS 决定设置 First Responder的唯一时间是文本字段获得焦点时。在所有其他时间,您必须明确控制您希望哪个对象成为第一响应者(请参阅 -canBecomeFirstResponder、-becomeFirstResponder)。

没有第二响应者之类的东西。

所有响应者都有一个NextResponder,(可以为零)。这意味着从任何响应者开始,可能(但可能不是)任意长度的响应者链(responseer -> nextResponder -> nextResponder -> etc),事件沿着这些链传递直到它们被处理。

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

默认链只是默认链,因此在您管理 First Responder 之后,您可以在其响应链中插入、删除和附加项目以实现您想要的目标。

响应者链非常重要且复杂,您应该花时间阅读有关它的 Apple 文档。

于 2011-07-19T22:53:27.583 回答
18

来自nextResponder的文档:

UIResponder 类不会自动存储或设置下一个响应者,而是默认返回 nil。子类必须重写此方法以设置下一个响应者。UIView 通过返回管理它的 UIViewController 对象(如果有)或其父视图(如果没有)来实现此方法;UIViewController 通过返回其视图的超级视图来实现该方法;UIWindow 返回应用程序对象,UIApplication 返回 nil。

于 2011-07-19T03:12:02.857 回答
6

应用程序使用响应者对象接收和处理事件。

响应者对象是UIResponder类的任何实例,

  • 常见的子类包括

    UIView、UIViewController 和 UIApplication

响应者接收原始事件数据,并且必须处理该事件或将其转发给另一个响应者对象。

当你的应用接收到一个事件时,UIKit 会自动将该事件定向到

  • 最合适的响应者对象,称为

    急救人员。

未处理的事件在活动响应者链中从响应者传递到响应者,

这是您应用的响应者对象的动态配置。

现在看下面的屏幕截图,还要考虑前面的 View-Hierarchies:

图像

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

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

这就是 Responder 链在 iOS 上的工作方式,希望对任何人都有帮助 另外 Apple 网站上的最新文章是 --> Link(很好解释。)

于 2018-08-21T14:14:07.713 回答
5

任何事件的响应者链是

UIView -> ViewController -> 窗口-> App Delegate

运行以下代码以更好地理解。

//
//  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)
    }
}
于 2017-09-02T14:24:27.663 回答
2

响应者链是一系列链接的响应者对象。它从第一响应者开始,到应用程序对象结束。如果第一响应者无法处理事件,它会将事件转发给响应者链中的下一个响应者。

响应者对象是可以响应和处理事件的对象。UIResponder 类是所有响应者对象的基类,它不仅为事件处理定义了编程接口,还为常见的响应者行为定义了编程接口。UIApplication、UIViewController 和 UIView 类的实例是响应者,这意味着所有视图和大多数关键控制器对象都是响应者。请注意,核心动画层不是响应者。

第一响应者被指定首先接收事件。通常,第一响应者是一个视图对象。一个对象通过做两件事成为第一响应者:

Overriding the canBecomeFirstResponder method to return YES.

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

有关更多说明,请参阅 Apple 文档。

于 2015-08-06T07:58:47.157 回答