iPhone: Change Keyboard language programmatically
Asked Answered
D

7

46

I am trying to provide a different language support on my iOS 5.x application whenever native Keyboard is opened. Provide this language in native keyboard programmatically. Could someone guide me how can i support it? I saw a carbon framework, but looks like its for Mac apps.

Thanks.

Defibrillator answered 26/9, 2012 at 6:42 Comment(1)
@Getsym, Please update the selected solution.Crim
V
7

No this is not possible - user can only change their language in the settings.

However you can give the user an "English" keyboard if you choose (or ask them their preference)

you do this using: UIKeyboardTypeASCIICapable

You can change keyboard directly on the keyboard by pressing "globe icon" on the bottom row.

First, you have to enable those language for input in Settings. Then pressing the globe button on the keyboard would toggle between those languages.

Vinegarish answered 26/9, 2012 at 6:45 Comment(5)
Hi, So, i can't programmatically allowed to change the keyboard language to different even with latest SDK also? I may show only english language keyboard if required to show a keyboard in within my app? Could you please provide me any apple link saying this is not possible, so i can read it more clearly, thank you very much.Defibrillator
I saw there is an option to 'Add New Keyboard..' in Keyboard settings on the iPhone. Can't we even install our own language file into it through our program or iTunes sync?Defibrillator
Yes in that we can't insert our own languageVinegarish
Maybe in 2012 it was not possible. Now by overriding textInputMode it is possible. See kotvaska answer. It works even for ios 11 :)Vaticination
In 2012 it was not possible. It became possible after by overriding textInputMode. However as of September 2019 with iOS 13 textInputMode's return value is ignored.Shoer
S
48

You can do it starting from iOS 7 on a per UIResponder basis. There is textInputMode property in UIResponder class. It is readonly, but the documentation says:

The text input mode identifies the language and keyboard displayed when this responder is active.

For responders, the system normally displays a keyboard that is based on the user’s language preferences. You can redefine this property and use it to return a different text input mode in cases where you want a responder to use a specific keyboard. The user can still change the keyboard while the responder is active, but switching away to another responder and then back restores the keyboard you specified.

In my project I created a subclass of UITextField and defined a new property called userDefinedKeyboardLanguage. I also overrode above mentioned textInputMode method. It looks similar to the following:

- (UITextInputMode *) textInputMode {
    for (UITextInputMode *tim in [UITextInputMode activeInputModes]) {
        if ([[Utilities langFromLocale:userDefinedKeyboardLanguage] isEqualToString:[Utilities langFromLocale:tim.primaryLanguage]]) return tim;
    }
    return [super textInputMode];
}

I have also a custom method +(NSString *)langFromLocale:(NSString *)locale in my Utilities class which looks like this:

+ (NSString *)langFromLocale:(NSString *)locale {
    NSRange r = [locale rangeOfString:@"_"];
    if (r.length == 0) r.location = locale.length;
    NSRange r2 = [locale rangeOfString:@"-"];
    if (r2.length == 0) r2.location = locale.length;
    return [[locale substringToIndex:MIN(r.location, r2.location)] lowercaseString];
}

Now my custom textfield class can change the keyboard input language simply by setting userDefinedKeyboardLanguage property to the desired language.

Schoolgirl answered 1/5, 2014 at 6:40 Comment(8)
My project is in Swift, but I found I needed to drop back to ObjC to override textInputMode.Challenge
how to ovverride textInputMode in swift?Metalanguage
Hai guys.., This works good with objC..What about swift..? @Chris,HovenSubsistent
can you please provide this in swift 3.0?Chaulmoogra
Thanks for the answer.Virge
This should most definitely be the answer.Institutionalize
Brilliant. But there's a problem (not your fault). If the user switches the keyboard to another language, the keyboard language continues to be reported, wrongly, as the tim language.Tremolo
It appears that ios 13 breaks the functionality: forums.developer.apple.com/thread/127668Kuopio
F
43

I know it is old question, but here it is my way to change keyboard language.

Thank to @the4kman for the mark: this way can change current keyboard only to those which were added in Settings.

Swift 3:

class CustomTextField: UITextField {

    private func getKeyboardLanguage() -> String? {
        return "en" // here you can choose keyboard any way you need
    }

    override var textInputMode: UITextInputMode? {
        if let language = getKeyboardLanguage() {
            for tim in UITextInputMode.activeInputModes {
                if tim.primaryLanguage!.contains(language) {
                    return tim
                }
            }
        }
        return super.textInputMode
    }

}
Farika answered 26/4, 2017 at 13:46 Comment(11)
Wow, i did not think that this was going to be possible but it works. iOS 10, Xcode 8 swift 3Lannie
Note that this can only change the keyboard to those which were added by the user in Settings.Overscrupulous
can you please provide code in swift 4 ? it is giving error for type as "Expression type '(_) -> _' is ambiguous without more context" & also in getKeyboardLanguage() function for switch cases.Festal
where to write this code ? In which class? can you please help me?Festal
@Festal I've edited my answer, take a look, please. This code works both in Swift 3 and Swift 4.Farika
In which setting do we need to add language?.I want he keyboard language support for French,Spanish,Chinese language for Decimal Pad keyboard type.Now I have added above code & set my textfiled's type to CustomTextField. any other changes do I need to do ?Festal
@Festal By telling Settings I mean iPhone app Settings. User can choose keyboards in General > Keyboard > Keyboards. And my answer works with these keyboards which were added by the user.Farika
Thanks @Farika for the solution. I found a problem that the keyboard is not switching to another language immediately. But after a click on the keyboard it switch to the language overridden.Mikaela
If there are some inputMode have the same primaryLanguage, how can I know which one is right?. In my case, Japanese Kana and Romaji have the same primaryLangue ja-JP.Smallminded
This no longer works as of iOS 13 (textInputMode return value is ignored by the keyboard). I think you can use this only to change to an English keyboard but nothing else. It's not clear if this is a bug or a "new feature." Everyone should file radars.Shoer
@Shoer I just tried it and it does not work in iOS 13.3, even for changing to English keyboard.Cloak
V
7

No this is not possible - user can only change their language in the settings.

However you can give the user an "English" keyboard if you choose (or ask them their preference)

you do this using: UIKeyboardTypeASCIICapable

You can change keyboard directly on the keyboard by pressing "globe icon" on the bottom row.

First, you have to enable those language for input in Settings. Then pressing the globe button on the keyboard would toggle between those languages.

Vinegarish answered 26/9, 2012 at 6:45 Comment(5)
Hi, So, i can't programmatically allowed to change the keyboard language to different even with latest SDK also? I may show only english language keyboard if required to show a keyboard in within my app? Could you please provide me any apple link saying this is not possible, so i can read it more clearly, thank you very much.Defibrillator
I saw there is an option to 'Add New Keyboard..' in Keyboard settings on the iPhone. Can't we even install our own language file into it through our program or iTunes sync?Defibrillator
Yes in that we can't insert our own languageVinegarish
Maybe in 2012 it was not possible. Now by overriding textInputMode it is possible. See kotvaska answer. It works even for ios 11 :)Vaticination
In 2012 it was not possible. It became possible after by overriding textInputMode. However as of September 2019 with iOS 13 textInputMode's return value is ignored.Shoer
B
7

Swift 5 implementation:

public extension UITextField 
{ 
    // ⚠️ Prefer english keyboards
    //
    override var textInputMode: UITextInputMode?
    {
        let locale = Locale(identifier: "en_US") // your preferred locale

        return
            UITextInputMode.activeInputModes.first(where: { $0.primaryLanguage == locale.languageCode })
            ??
            super.textInputMode
    }
}
Bibliophile answered 29/4, 2020 at 12:54 Comment(2)
I used this solution but not working. My app have decimal type keyboard to enter float values and when I select English it's working fine and showing decimal point but whenever I selects German or French, decimal point should get changed to comma but this is not happening even I am setting textInputMode to German or French.Staghound
Also if I killed my app and restart then decimal point is reflected as a comma. Not sure what is the isssue with this.Staghound
O
6

Declaration:

@IBOutlet var yourTextField:cTextField!;

Use:

yourTextField.languageCode = "ru";

Class cTextField:

class cTextField: UITextField {

    // ru, en, ....
    var languageCode:String?{
        didSet{
            if self.isFirstResponder{
                self.resignFirstResponder();
                self.becomeFirstResponder();
            }
        }
    }

    override var textInputMode: UITextInputMode?{
        if let language_code = self.languageCode{
            for keyboard in UITextInputMode.activeInputModes{
                if let language = keyboard.primaryLanguage{
                    let locale = Locale.init(identifier: language);
                    if locale.languageCode == language_code{
                        return keyboard;
                    }
                }
            }
        }
        return super.textInputMode;
    }
}
Overjoy answered 4/6, 2018 at 14:17 Comment(2)
This works but I can't use it as I have to change all my UITextFields to a new cTextField. I want some extension to existing UITextFieldChoroid
This is the only working solution for me as of June 2023, on iOS 16.Moil
N
6

All great answers. But in Swift you can override methods and variables defined in parent class (UIResponder) in an extension. So it's not necessary to subclass. And it's nice to replace the for loop with a more swift like one-liner.

public extension UITextField {  
    override var textInputMode: UITextInputMode? {
        return UITextInputMode.activeInputModes.filter { $0.primaryLanguage == "emoji" }.first ?? super.textInputMode
    }
}

Instead of "emoji" probably will be something like Utils.currentAppLanguage

Nobukonoby answered 16/12, 2019 at 13:4 Comment(0)
O
3

This seems to work to change, for instance, to a Greek keyboard:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"el", nil] 
    forKey:@"AppleLanguages"]; 

[[NSUserDefaults standardUserDefaults] synchronize]; 
Oneupmanship answered 16/11, 2012 at 16:35 Comment(1)
Is this still working? I'm trying with iOS 7 and it doesn't seem to change the keyboard, it remains in English.Mccollum

© 2022 - 2024 — McMap. All rights reserved.