Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to detect when the iOS default keyboard type switches from text to numbers

There are many posts about notifying the user when the keyboard type changes from things like the numberpad to default. This question is about knowing about when the user actually clicks on the [123] or the [ABC] button on the default keypad.. basically I want to know when this screen

enter image description here

changes to this screen

enter image description here

trying this:

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSLog(@"::::::: this is text field type %d", searchBar.keyboardType);

naturally always give me back 0 which is the default key type.. since it's assuming both are of the same keyboard type.

like image 329
abbood Avatar asked Jan 21 '14 10:01

abbood


People also ask

How do I calibrate my iPhone keyboard?

To reset the iOS keyboard, perform these steps: Open the Settings app. Select General | Reset. Select Reset Keyboard Dictionary and then type in your iOS passcode to continue with the reset (Figure C).

How do I change the default keyboard language on my iPhone?

Go to Settings > General > Keyboard > Keyboards. Tap a language at the top of the screen, then select an alternative layout from the list.


1 Answers

I ran into this same issue today and was sort of astounded that there is no way to detect that change from any notification or delegate method as I think this is a fairly common need. I am building a multi field text box input for capturing a pin code. I am auto-advancing to next / previous fields upon entering a value and don't want the keyboard to switch back to default each time I switch fields. I came up with this solution (note: This doesn't solve it perfectly because it requires the user to type something, but solves it for similar needs to this pin view).

I have a custom view called MyPinView, this view has var

var keyBoardType = UIKeyboardType.alphabet

and an array of UITextFields

var pinFields = [UITextField]()

that is laid out like so. enter image description here

For a simplified version, I won't go through all the details of handling edge cases that require shouldChangeCharactersInRange to be implemented and will stick with my event handler implementation.

Basically, you need to see what text was typed and determine what keyboard to show when advancing fields (mine only supports numbers and letters switched with the abc / 123 button so I will ignore emoji and other types).

// MARK: UITextField Event
func textFieldDidChange(textField: UITextField) {
    // If the user typed one character, move to the next cell.
    if (textField.text?.count == 1) {
        let index = pinFields.index(of: textField)
        textField.resignFirstResponder()
        if (pinFields.count > index! + 1) {
            let pinField = pinFields[index! + 1]
            self.updateKeyboardTypeForString(input: textField.text)
            pinField.keyboardType = self.keyBoardType
            pinField.becomeFirstResponder()
        }
    } // If they deleted the character move to previous cell
    else if (textField.text?.count == 0) {
        let index = pinFields.index(of: textField)
        if (index! - 1 >= 0) {
            let pinField = pinFields[index! - 1]
            self.updateKeyboardTypeForString(input: pinField.text)
            pinField.keyboardType = self.keyBoardType
            pinField.becomeFirstResponder()
        }
    }
}

// MARK: - Keyboard Type Helper
func updateKeyboardTypeForString(input:String?) {
    let letters = NSCharacterSet.letters
    let digits = NSCharacterSet.decimalDigits
    let pinText = input == nil ? "" : input
    for uniScalar in pinText!.unicodeScalars {
        if letters.contains(uniScalar) {
            self.keyBoardType = UIKeyboardType.alphabet
        } else if digits.contains(uniScalar) {
            self.keyBoardType = UIKeyboardType.numbersAndPunctuation
        }
    }
}

This allows you to track where the keyboard last left off. Obviously if your text fields allow more than one character, you would need to grab only the last types character and pass it to updateKeyboardTypeForString. The main case where this won't help is in preserving keyboard state between input fields where the user has switched the keyboard, but not typed anything. Overall though, this helps this type of scenario to be more usable.

Hope this helps, happy programming.

like image 122
johnrechd Avatar answered Oct 05 '22 23:10

johnrechd