Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

У всех респондентов есть NextResponder, который может быть равен нулю. Это означает, что, начиная с любого ответчика, может существовать (но может и не быть) цепочка ответчиков с произвольной длиной (responder → nextResponder → nextResponder → и т.д.), по которой события передаются до тех пор, пока они не будут обработаны.

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

Цепочка по умолчанию - это только значение по умолчанию, поэтому после того, как вы управляете Первым Ответчиком, вам нужно вставлять, удалять и добавлять элементы к цепочке ответчиков для достижения желаемой цели.

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

Ответ 2

Из документов для nextResponder:

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

Ответ 3

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

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

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

Overriding the canBecomeFirstResponder method to return YES.

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

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

Ответ 4

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

UIView → ViewController → Window- > 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)
    }
}