Danya
Danya

Reputation:

Detecting current iPhone input language

Does anybody knows, can I get the current input language and/or keyboard layout in iPhone application? Can I also get a notification when input language was changed?

Upvotes: 19

Views: 20888

Answers (6)

kirander
kirander

Reputation: 2256

You can ask current first responder (UITextField, UISearchBar, etc.) via UIResponder method textInputMode:

// assume you have instance variable pointing to search bar currently entering
UITextInputMode *inputMode = [self.searchBar textInputMode];
NSString *lang = inputMode.primaryLanguage;

Upvotes: 17

andershqst
andershqst

Reputation: 1464

In line with the top answers, the following is a generic solution to getting the keyboard language whenever it is changed. Register for the notification UITextInputCurrentInputModeDidChangeNotification:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputModeDidChange:) name:UITextInputCurrentInputModeDidChangeNotification object:nil];

Then in inputModeDidChange

-(void)inputModeDidChange:(NSNotification *)notification {
   UIView *firstResponder = [UIView currentFirstResponder];
   UITextInputMode *currentInputMode =  firstResponder.textInputMode;
   NSString *keyboardLanguage = [currentInputMode primaryLanguage];
   NSLog(@"%@", keyboardLanguage); // e.g. en-US
}

Where currentFirstResponder is from a category on UIView to get the first responder view, as suggested in this SO post:

//  UIView+Additions.h 
#import <UIKit/UIKit.h>
@interface UIView (Additions)
+ (id)currentFirstResponder;
@end

Implementation

//  UIView+Additions.m
#import "UIView+Additions.h"
static __weak id currentFirstResponder;
@implementation UIView (Additions)
+ (id)currentFirstResponder {
    currentFirstResponder = nil;
    // This will invoke on first responder when target is nil
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:)
                                           to:nil
                                         from:nil
                                     forEvent:nil];
    return currentFirstResponder;
}

- (void)findFirstResponder:(id)sender {
    // First responder will set the static variable to itself
    currentFirstResponder = self;
}
@end

Upvotes: 2

Vincent Gable
Vincent Gable

Reputation: 3465

In iOS 4.2 and later, you can use the UITextInputMode class to determine the primary language currently being used for text input.

[UITextInputMode currentInputMode].primaryLanguage will give you an NSString representing the BCP 47 language code such as “es”, “en-US”, or “fr-CA”.

You can register for the UITextInputCurrentInputModeDidChangeNotification to be alerted when the current input mode changes.

(You might also be interested in the "Getting Your Apps Ready for China and other Hot New Markets" WWDC session, and Internationalization Programming Topics.)

Upvotes: 29

MyCSharpCorner
MyCSharpCorner

Reputation: 1313

The way I would do it is as follows:

  • Register your ViewController as a listener to UIApplicationDidBecomeActiveNotification

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];

  • In applicationDidBecomeActive handler, check the current language using [NSLocale preferredLanguages] and act upon it accordingly.

This approach gives you what you want and is totally shippable without having to use private API.

Upvotes: 1

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81848

You can add an observer to the default notification center:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(inputModeDidChange:)
                                             name:@"UIKeyboardCurrentInputModeDidChangeNotification"
                                           object:nil];

This method prints the currently selected input language (like "en_US" or "de_DE"):

- (void)inputModeDidChange:(NSNotification*)notification
{
    id obj = [notification object];
    if ([obj respondsToSelector:@selector(inputModeLastUsedPreference)]) {
        id mode = [obj performSelector:@selector(inputModeLastUsedPreference)];
        NSLog(@"mode: %@", mode);
    }
}

BUT: All the above is not documented and you should not use it in shipping code!

Upvotes: 8

Alex Reynolds
Alex Reynolds

Reputation: 96927

From the Apple Reference Library - "Getting the Current Language and Locale":

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

Upvotes: 5

Related Questions