Как работает сеть Responder в IPhone? Каковы "следующие ответчики"?

вот что говорится в документации:

Если первый ответчик [на сообщение о событии или действии] не может обработать сообщение о событии или действии, он перенаправляет его "следующему ответчику" в связанном ряду, называемом цепочкой ответчика. Цепочка ответчика позволяет объектам ответчика передавать ответственность за обработку сообщения о событии или действии другим объектам приложения.

Если объект в цепочке ответчика не может обработать событие или действие, он повторно отправляет сообщение следующему ответчику в цепочке. Сообщение движется вверх по цепочке, к объектам более высокого уровня, пока не будет обработано. Если он не обрабатывается, приложение отбрасывает его.

хорошо, какой следующий ответчик?

Это Родительский вид? Вид за ним? Как iOS решает, что является первым ответчиком и вторым ответчиком?

5 ответов


первый ответчик-очень специфическая концепция в Cocoa. Единственный раз iOS решает установить первый ответчик, когда текстовое поле получает фокус. Во всех остальных случаях вы должны явно контролировать, какой объект вы хотите быть первым ответчиком (см.-canBecomeFirstResponder, -becomeFirstResponder).

нет такой вещи, как второй ответчик.

все ответчики имеют NextResponder (который может быть nil). Это означает, что начало от любого ответчика может быть (но не может быть) цепь ответчиков произвольной длины (ответчик - > nextResponder - > nextResponder - > etc), по которым передаются события, пока они не будут обработаны.

существует цепочка по умолчанию, которая может быть view - > superview - > superview, но также может включать UIViewControllers, UIWindows, UIWindowControllers, UIApplication и многое другое, поэтому это сильно зависит от вашей иерархии объектов (а не только от иерархии представлений-так нет, вы не можете сказать nextResponder всегда родительское представление). В OSX 10.6 цепочка по умолчанию даже отличается для разных типов событий и действий и может даже включать делегат вашего приложения, который может быть или не быть ответчиком, я не уверен, что это так в iOS tho.

цепочка по умолчанию является только по умолчанию tho, поэтому после того, как вы управляете первым ответчиком, вам нужно вставить, удалить и добавить элементы в цепочку ответчика, чтобы достичь желаемого цель.

цепочка ответчика довольно важна и сложна, вам нужно время, чтобы прочитать документы Apple об этом.


документы на nextResponder:

класс UIResponder не хранит и следующей ответчика автоматически, вместо возврата nil по умолчанию. Подклассы должны переопределите этот метод, чтобы задать следующий респондент. Ему UIView реализует этот метод, возвращая объект UIViewController, который управляет им (если он имеет один) или его superview (если это не так); UIViewController реализует метод, возвращая супервизор своего представления; UIWindow возвращает объект приложения и UIApplication возвращает nil.


цепочка ответчика для любого события

UIView - > ViewController - > Окно - > Делегат Приложения

выполнить ниже код для лучшего понимания.

//
//  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)
    }
}

цепочка ответчика представляет собой ряд связанных объектов ответчика. Он начинается с первым и объект приложения. Если первый ответчик не может обработать событие, он перенаправляет событие следующему ответчику в цепочке ответчиков.

объект ответчика-это объект, который может отвечать на события и обрабатывать их. Класс UIResponder является базовым классом для всех объектов responder и определяет программный интерфейс не только для обработки событий, но и для common поведение ответчика. Экземпляры классов UIApplication, UIViewController и UIView являются ответчиками, что означает, что все представления и большинство ключевых объектов контроллера являются ответчиками. Обратите внимание, что слои Core Animation не являются ответчиками.

первый ответчик предназначен для получения событий в первую очередь. Как правило, первым ответчиком является объект view. Объект становится первым ответчиком, делая две вещи:

Overriding the canBecomeFirstResponder method to return YES.

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

обратитесь к Apple doc для получения дополнительных объяснений.


приложения получают и обрабатывают события с помощью объектов ответчика.

объект ответчика-это любой экземпляр UIResponder класса,

  • общие подклассы включают в себя

    UIView, UIViewController и UIApplication.

ответчики получают необработанные данные события и должны либо обработать событие, либо переслать его другому объекту ответчика.

когда ваш приложение получает событие, UIKit автоматически направляет это событие в

  • наиболее подходящий объект ответчика, известный как

    первый ответчик.

необработанные события передаются от ответчика к ответчику в активной цепочке ответчика,

который является динамической конфигурацией объектов ответчика вашего приложения.

теперь посмотрите на снимок экрана ниже, также рассмотрите вид-иерархии спереди:

img

UIbutton / UITextField --(nextResponder)-> - наследник UIView --(nextResponder)-> UIViewController

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

вот как Сеть ответчиков работает на iOS, надеюсь, что это поможет кому-нибудь также Последняя статья на веб-сайте Apple ->ссылке (очень хорошо объяснил.)