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.
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.
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
}
}
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.
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
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;
}
}
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
}
}
This seems to work to change, for instance, to a Greek keyboard:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"el", nil]
forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
Related
I am new to swift and i am playing around with a little converter app. I Have two TextFields and one "convert" button.
I want to overwrite the non acticv Textfield with the converted value from the last activ TextField.
I know it would be easier with more Textfields and more buttons but i would like to solve it this way.
Can anybody give me an advise?
var NumberC = Int(InputCelcius.text!)!
var NumberF = Int(InputFahrenheit.text!)!
if InputCelcius.isFirstResponder {
if (InputCelcius.text?.isEmpty)! {
NumberC=0
print("NumberC is empty")
}
NumberC = NumberC * 9/5 + 32
InputFahrenheit.text = " \(NumberC)"
}
else if InputFahrenheit.isFirstResponder {
if (InputFahrenheit.text?.isEmpty)! {
NumberF=0
print("NumberF is empty")
}
NumberF = (NumberF - 32) * 5/9
InputCelcius.text = " \(NumberF)"
}
I’d suggest using the UITextFieldDelegate function textFieldDidEndEditing. Make sure you subclass your viewController as a UITextFieldDelegate.
class ViewController: UIViewController, UITextFieldDelegate {
Set each textField's delegate to self in viewDidLoad.
override func viewDidLoad() {
super.viewDidLoad()
InputFahrenheit.delegate = self
InputCelsius.delegate = self
}
With this method you wouldn't even need a UIButton, but you could use the button to force the textField to end editing like this.
#objc func buttonAction (sender: UIButton) {
self.view.endEditing(true)
}
Which will call this delegate method if the user was editing a textField.
func textFieldDidEndEditing (textField: UITextField) {
if textField.isEmpty {return} //this prevents nil errors and user would have to type in "0" if wishing to convert zero.
if textField == InputCelsius {
let conversion = Float(textField.text!) * 9/5 + 32
InputFahrenheit.text = String(format: “%.f”, conversion) //“%.1f” will show one decimal place and so forth
} else if textField == InputFahrenheit {
let conversion = ( Float(textField.text!) - 32 ) * 5/9
InputCelsius.text = String(format: “%.f”, conversion)
}
}
I‘m not quite sure about that but I think if you press the button, the button itself will become first responder, so your code won‘t work.
The proper way to do that, would be to set IBAction functions that get called when you finish editing one of your textfields. Just connect the Textfields inside your storyboard to the code like you did it with your button.
Then you can set up two functions, one for each of the textfields, so you don‘t have to worry about firstresponder.
How do I create outlets for my keys in a custom keyboard to switch from letters to numbers and symbols? I am trying to create a custom keyboard and I don't know how to create outlets for my keys to switch back and forth from letters to numerals and symbols.
So, I gather from your comment, that this is what you are looking for. The type of keyboard input, is determined by setting the 'keyboardType' property of the keyboard's delegate. If you want to switch and update a view, I think you'll have to dismiss the keyboard and recall it. I find this unsafe, and would highly suggest using a normal keyboard (which has all the characters you need), trusting your user, and sanitizing the input. But the following does work, if you must. In the following, 'txtField' is a UITextField with the UIViewController set as its delegate, the IBAction is wired to a UIButton, and 'isNumbers' is a Bool property of the UIViewController.
#IBAction func switchKeyboards(_ sender: Any) {
if isNumbers {
txtField.keyboardType = UIKeyboardType.alphabet
isNumbers = false
} else {
txtField.keyboardType = UIKeyboardType.numberPad
isNumbers = true
}
txtField.resignFirstResponder()
txtField.becomeFirstResponder()
}
How to determine which text field is active ? (which one have the focus on it).
I found this code in objective-C but don't know how if it is still working and how to translate it in swift
NSResponder *firstResponder = [[NSApp keyWindow] firstResponder];
if ([firstResponder isKindOfClass:[NSText class]] && [(id)firstResponder delegate] == mySearchField) {
NSLog(#"Yup.");
}
Here you go:
var responder = window.firstResponder
if responder.isKind(of: NSText.self) {
let fieldEditor = responder as! NSText
responder = fieldEditor.delegate as! NSResponder
}
At the end is responder the focused control. If the focused control is a NSTextField then the first responder is the field editor, a NSTextView inside the text field. The delegate of the field editor is the control.
Umm here is how I would do it in iOS if anyone is interested. I am not familiar with how Mac OS deals with firstResponder, but it looks to be quite different.
func findFirstResponder(in view: UIView) -> UIView? {
for subview in view.subviews {
if subview.isFirstResponder {
return subview
}
if let firstReponder = findFirstResponder(in: subview) {
return firstReponder
}
}
return nil
}
You can do an if else and iterate over each textField so you can know what textField is the firstResponder.
func methodForDiscoverTheFirstResponder {
if myTextField.isFirstResponder {
//do stuff
} else if mySecondTextField.isFirstResponder {
//do stuff
}
...
}
I use a couple of buttons '0123456789.' (and some others) as an alternative for a keyboard. They are connected to (several) texfields. I made them all programmatically, so without storyboard. I also use UITextFieldDelegate. That works as expected, and I can input my text into the textfields.
I use the following code for my buttons:
func textFieldDidBeginEditing(textField: UITextField) {
activeField = textField
}
#IBAction func Pressed(sender: UIButton) {
if (activeField != nil) {
switch sender.tag {
case 0:
activeField!.text = activeField!.text+"0"
case 1:
The problem is that every-time I click in a textfield, the keyboard opens up too. I want to avoid that... since I made an alternative for input with the buttons. How can I get rid of the keyboard when I click in a textfield?
Just return NO from textFieldShouldBeginEditing: from the delegate you mention you are already using.
When the user performs an action that would normally initiate an editing session, the text field calls this method first to see if editing should actually proceed. In most circumstances, you would simply return YES from this method to allow editing to proceed.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField == /* a text field that is using your custom layout */)
return NO;
}
[Source]
Though why don't you just use [textField setKeyboardType:UIKeyboardTypeNumberPad];
You should make your custom keypad the inputView of the textField. It will then be shown instead of the built-in keyboard.
i.e.:
textField.inputView = yourCustomKeypad;
I've made a similar input interface, using custom buttons...why not instead of a UITextField, use a UILabel to display the "8,900"(input).
Then just make the buttons manipulate the UILabel.text.
I have an app with a login page that has three fields for three different random characters. When the user leaves the last field, the soft keyboard disappears and the user can touch a "login" button on screen.
When there is a hardware keyboard (bluetooth or physical) attached, I'd like to be able to hit "enter" on it. However because the user is not in a field, I can't see how to detect this key being pressed.
Would anyone have advice on which class handles key press events? Presumably there is a delegate that I can use to receive these but my searches through the SDK haven't found anything.
Thanks
For iOS 7.0 or later, you can return UIKeyCommands for the keyCommands property from any UIResponder, such as UIViewController:
Objective-C
// In a view or view controller subclass:
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (NSArray *)keyCommands
{
return #[ [UIKeyCommand keyCommandWithInput:#"\r" modifierFlags:0 action:#selector(enterPressed)] ];
}
- (void)enterPressed
{
NSLog(#"Enter pressed");
}
Swift
// In a UIView/UIViewController subclass:
override var canBecomeFirstResponder: Bool {
true
}
override var keyCommands: [UIKeyCommand]? {
return [ UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(enterPressed)) ]
}
#objc func enterPressed() {
print("Enter pressed")
}
One way to accomplish this is to have a hidden extra (4th in your case) text field. Make it 1x1 px in size and transparent. Then make it the first responder when any of your other 3 text fields are not, and look for text change events in that hidden field to trigger your key input event.
You might also want to check the notification for a software keyboard appearing if you don't want it to stay visible as well.
As a followup to the response by #Patrick, here is how you do it in Xamarin.iOS:
public override bool CanBecomeFirstResponder
{
get { return true; }
}
public override UIKeyCommand[] KeyCommands
{
get
{
return new[]{ UIKeyCommand.Create((NSString)"\r", (UIKeyModifierFlags)0, new ObjCRuntime.Selector("enterPressed")) };
}
}
[Export("enterPressed")]
private void OnEnterPressed()
{
// Handle Enter Key
}