¿Cómo funciona la cadena de respuesta en el iPhone? ¿Cuáles son los "siguientes respondedores"?
objective-c ios (5)
Esto es lo que dice la documentación:
Si el primer respondedor [a un mensaje de evento o acción] no puede manejar un evento o mensaje de acción, lo reenvía al "siguiente respondedor" en una serie vinculada llamada cadena de respondedores. La cadena de respondedores permite que los objetos respondedores transfieran la responsabilidad de manejar un evento o mensaje de acción a otros objetos en la aplicación.
Si un objeto en la cadena de respondedores no puede manejar el evento o la acción, reenvía el mensaje al siguiente respondedor de la cadena. El mensaje viaja hacia la cadena, hacia objetos de nivel superior, hasta que se maneja. Si no se maneja, la aplicación lo descarta.
Bien, ¿cuál es el siguiente respondedor?
¿Es la vista padre? La vista detrás de esto? ¿Cómo decide iOS qué es el primer respondedor y el segundo respondedor?
De los documentos para el nextResponder :
La clase UIResponder no almacena ni establece el siguiente respondedor automáticamente, en lugar de eso devuelve nil de forma predeterminada. Las subclases deben anular este método para establecer el siguiente respondedor. UIView implementa este método devolviendo el objeto UIViewController que lo administra (si tiene uno) o su supervisión (si no lo tiene); UIViewController implementa el método devolviendo la vista de supervisión de su vista; UIWindow devuelve el objeto de la aplicación y UIApplication devuelve nil.
La cadena de respondedores es una serie de objetos respondedores vinculados. Comienza con el primer respondedor y termina con el objeto de la aplicación. Si el primer respondedor no puede manejar un evento, lo envía al siguiente respondedor en la cadena de respondedores.
Un objeto respondedor es un objeto que puede responder y manejar eventos. La clase UIResponder es la clase base para todos los objetos de respuesta, y define la interfaz programática no solo para el manejo de eventos sino también para el comportamiento común de respuesta. Las instancias de las clases UIApplication, UIViewController y UIView son respondedores, lo que significa que todas las vistas y la mayoría de los objetos clave del controlador son respondedores. Tenga en cuenta que las capas Core Animation no responden.
El primer respondedor está designado para recibir eventos primero. Típicamente, el primer respondedor es un objeto de vista. Un objeto se convierte en el primer respondedor haciendo dos cosas:
Overriding the canBecomeFirstResponder method to return YES.
Receiving a becomeFirstResponder message. If necessary, an object can send itself this message.
Consulte Apple doc para más explicación.
La cadena de respuesta para cualquier evento es.
UIView -> ViewController -> Window-> App Delegate
Ejecute el siguiente código para una mejor comprensión.
//
// 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)
}
}
Las aplicaciones reciben y manejan eventos usando objetos de respuesta.
Un objeto respondedor es cualquier instancia de la clase UIResponder ,
subclases comunes incluyen
UIView, UIViewController y UIApplication .
Los respondedores reciben los datos brutos del evento y deben manejar el evento o reenviarlo a otro objeto respondedor.
Cuando su aplicación recibe un evento, UIKit dirige automáticamente ese evento a la
objeto respondedor más apropiado, conocido como el
primer respondedor
Los eventos no controlados se pasan del respondedor al respondedor en la cadena de respondedores activos,
que es la configuración dinámica de los objetos de respuesta de su aplicación.
Ahora mire la captura de pantalla de abajo, también considere las jerarquías de vista desde el frente:
UIbutton / UITextField - (nextResponder) -> UIView - (nextResponder) -> UIViewController
- (nextResponder) -> UIWindow - (nextResponder) -> UIApplication - (nextResponder) -> UIApplicationDelegate
Así es como funciona la cadena de respuesta en iOS, espero que ayude a cualquiera También el último artículo en el sitio web de Apple es -> Link (muy bien explicado).
The First Responder es un concepto muy específico en Cocoa. La única vez que iOS decide establecer el Primer Servicio de Respuesta es cuando un campo de texto se enfoca. En cualquier otro momento, debe controlar explícitamente qué objeto desea que sea el primer respondedor (consulte -canBecomeFirstResponder, -becomeFirstResponder).
No hay tal cosa como un segundo respondedor.
Todos los respondedores tienen un NextResponder , (que puede ser nulo). Esto significa que a partir de cualquier respondedor puede haber (pero no puede haber) una cadena de respondedores de longitud arbitraria ( respondedor -> nextResponder -> nextResponder -> etc ) a lo largo de los cuales se pasan los eventos hasta que se manejan.
Existe una cadena predeterminada que se puede ver -> superview -> superview pero también puede incluir UIViewControllers, UIWindows, UIWindowControllers, UIApplication y más, por lo que depende en gran medida de su jerarquía de objetos (no solo su jerarquía de vistas, así que no puede t decir nextResponder es siempre la vista principal). En OSX 10.6, la cadena predeterminada es incluso diferente para diferentes tipos de eventos y acciones, e incluso puede incluir su delegado de aplicación, que puede o no ser un respondedor, no estoy seguro de que este sea el caso en iOS.
La cadena predeterminada es solo la predeterminada, por lo que, una vez que haya administrado el Primer Respondedor, podrá insertar, eliminar y agregar elementos a su cadena de respondedores para lograr el objetivo deseado.
La cadena de respuesta es bastante importante y complicada, debe tomarse el tiempo para leer la documentación de Apple al respecto.