Search code examples
iosobjective-ccocoa-touchuitextfielduikit

Is it possible to get textfield assosiated with a keyboard?


In my view controller I'm subscribed to UIKeyboardWillShowNotification:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

so in my keyboardWillShow: method I'm able to retrieve some info about the keyboard from the notification. But what I want is to get the reference to the actual text field which brings the keyboard up. I couldn't find how to do that in google and I suspect it might be impossible, but someone might know. If it is indeed impossible then I would like to know if there's a possibility to make it reverse way - to get the info about the keyboard by having the reference to the text field. Thanks


Solution

  • Let me emphasize that @iphonic comment is the right way to go.

    You should use UITextField delegate function textFieldShouldBeginEditing:

    Anything short of that is a kludge: UIKeyboardWillShowNotification assumes the software keyboard will show up, with is a very dangerous assumption and is likely to fail in all sorts of situations, starting with but not limited to Bluetooth keyboards. Try cmd-K in Simulator.

    Here is aforementioned kludge, inspired by Get the current first responder without using a private API

    func keyboardWillShow() {
        let firstResponder = self.findFirstResponder(inView: self.view)
        println("keyboardWillShow for \(firstResponder)")
    }
    
    func findFirstResponder(inView view: UIView) -> UIView? {
        for subView in view.subviews as! [UIView] {
            if subView.isFirstResponder() {
                return subView
            }
    
            if let recursiveSubView = self.findFirstResponder(inView: subView) {
                return recursiveSubView
            }
        }
    
        return nil
    }