Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting 'Return' key pressed from an external keyboard on iOS

Is there a way to detect when the "Return" key is pressed from an external keyboard connected to an iOS device as opposed to a tap on the onscreen keyboard's "Return" key?

Is this possible with public APIs?

My class is serving as UITextFieldDelegate and I get the call from:

- (BOOL)textFieldShouldReturn:(UITextField *)textField

But when it's called, textField.text returns the characters present in the text field but not the carriage return that was issued.

-textField:shouldChangeCharactersInRange:replacementString isn't invoked with the "Return" key press for both physical or virtual keyboards.

like image 290
Paul Hansen Avatar asked Nov 07 '25 02:11

Paul Hansen


2 Answers

In iOS 7+, you can use UIKeyCommand to distinguish Return via hardware keyboard.

extension ViewController {
    override var keyCommands: [UIKeyCommand]? {
        return [
            UIKeyCommand(input: "\r",
                         modifierFlags: [],
                         action: #selector(didPressReturnOnHardwareKeyboard)),
        ]
    }
    
    @objc
    private func didPressReturnOnHardwareKeyboard() {
        // Handle action.
    }
}
like image 73
fumoboy007 Avatar answered Nov 09 '25 19:11

fumoboy007


A subclass of UITextField should work:

protocol TextFieldKeyDetectionDelegate: AnyObject {
    func enterKeyWasPressed(textField: UITextField)
    func shiftEnterKeyPressed(textField: UITextField)
}

class TextFieldWithKeyDetection: UITextField {
    weak var keyDelegate: TextFieldKeyDetectionDelegate?
    
    override var keyCommands: [UIKeyCommand]? {
        [UIKeyCommand(input: "\r", modifierFlags: .shift, action: #selector(shiftEnterKeyPressed)),
         UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(enterKeyPressed))]
    }
    
    @objc func shiftEnterKeyPressed(sender: UIKeyCommand) {
        keyDelegate?.shiftEnterKeyPressed(textField: self)
    }
    
    @objc func enterKeyPressed(sender: UIKeyCommand) {
        keyDelegate?.enterKeyWasPressed(textField: self)
    }
}
like image 33
sash Avatar answered Nov 09 '25 19:11

sash