skip to Main Content

I having trouble in understanding First Responder. My Understanding is as follows.

First Responder is the first object in the responder chain which gets first oppurtunity to handle Any UIEvent.

UIKit starts finding the location of the tap. It uses a hit test API of the UIView that traverses to the deepest level of the hierarchy to find the specific touch. After finding the view, it assigns the first responder of the touch event to that view.

So when we find the view on which touch occurs then checking isFirstResponder to that view is still false. Can someone explain me? Why isFirstResponder still holding false? Even if this is the first view whose touch began is calling.

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if touches.first?.view?.isFirstResponder == true {
            print("Top View is firstResponder ")
        }
        super.touchesBegan(touches, with: event)
    }

I have checked with the above code by overriding this method on top view which added on UIViewController View.

2

Answers


  1. First responders follow a hierarchical chain and while you may tap on a view, you have to consider the view controller going higher up, or the sub elements of the view going deeper into the hierarchy. Apple’s guide on first responders might help clarify this chain. https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/using_responders_and_the_responder_chain_to_handle_events

    Login or Signup to reply.
  2. because this is the touched view but not the first responder in view,

    UIKit manages the responder chain dynamically, using predefined rules.

    UIKit dispatches some types of events, such as motion events, displaying the object’s input view to the first responder.

    try to add a text field in the view, touches began will not fire when selecting uitextfield, and while the keyboard appears tap anywhere in the view touches began will fire and the text field is still the first reponder.
    The system’s keyboard is the most obvious example of an input view. When the user taps a UITextField, it becomes the first responder and displays its input view (the system keyboard).

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(touches.first?.view?.firstResponder)
        super.touchesBegan(touches, with: event)
    }
    
    extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }
    
        for subview in subviews {
            if let firstResponder = subview.firstResponder {
                return firstResponder
            }
        }
    
        return nil
    }
    

    }

    check this
    Get the current first responder without using a private API

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search