【问题标题】:iPhone: Change Keyboard language programmaticallyiPhone:以编程方式更改键盘语言
【发布时间】:2012-09-17 17:44:15
【问题描述】:

每当打开本机键盘时,我都会尝试在我的 iOS 5.x 应用程序上提供不同的语言支持。以编程方式在本机键盘中提供此语言。有人可以指导我如何支持它吗?我看到了一个碳框架,但它看起来像是用于 Mac 应用程序的。

谢谢。

【问题讨论】:

  • @Getsym,请更新所选解决方案。

标签: iphone iphone-softkeyboard


【解决方案1】:

您可以从 iOS 7 开始基于每个 UIResponder 执行此操作。 UIResponder 类中有 textInputMode 属性。它是只读的,但文档说:

文本输入模式识别显示的语言和键盘 当此响应者处于活动状态时。

对于响应者,系统通常会显示一个基于 关于用户的语言偏好。您可以重新定义此属性并 在您想要一个 响应者使用特定的键盘。用户仍然可以更改 响应者处于活动状态时的键盘,但切换到另一个 响应者,然后返回恢复您指定的键盘。

在我的项目中,我创建了UITextField 的子类并定义了一个名为 userDefinedKeyboardLanguage 的新属性。我还覆盖了上面提到的 textInputMode 方法。它看起来类似于以下内容:

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

我的 Utilities 类中还有一个自定义方法 +(NSString *)langFromLocale:(NSString *)locale,如下所示:

+ (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];
}

现在我的自定义文本字段类可以通过将 userDefinedKeyboardLanguage 属性设置为所需的语言来更改键盘输入语言。

【讨论】:

  • 太棒了!这应该是答案。
  • 我的项目在 Swift 中,但我发现我需要退回到 ObjC 来覆盖 textInputMode。
  • 如何在 swift 中覆盖 textInputMode?​​span>
  • 这绝对是答案。
  • 太棒了。但是有一个问题(不是你的错)。如果用户将键盘切换到另一种语言,则会继续将键盘语言错误地报告为tim 语言。
【解决方案2】:

我知道这是个老问题,但这是我更改键盘语言的方法。

感谢@the4kman 的标记:这种方式只能将当前键盘更改为设置中添加的键盘。

斯威夫特 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
    }

}

【讨论】:

  • 哇,我不认为这是可能的,但它确实有效。 iOS 10、Xcode 8 Swift 3
  • 请注意,这只能将键盘更改为用户在设置中添加的键盘。
  • 能否提供 swift 4 中的代码?它给出了类型错误,因为“表达式类型 '(_) -> _' 在没有更多上下文的情况下是模棱两可的”,并且在开关情况下的 getKeyboardLanguage() 函数中也是如此。
  • 这不再适用于 iOS 13(键盘忽略 textInputMode 返回值)。我认为您只能使用它来更改为英文键盘,但不能使用其他任何东西。目前尚不清楚这是错误还是“新功能”。每个人都应该提交雷达。
  • @dbquarrel 我刚试了下,iOS 13.3 也不能用,换英文键盘也不行。
【解决方案3】:

不,这是不可能的 - 用户只能在设置中更改他们的语言。

但是,如果您选择(或询问他们的偏好),您可以给用户一个“英文”键盘

您可以使用:UIKeyboardTypeASCIICapable

您可以通过按底部行的“地球图标”直接在键盘上更改键盘。

首先,您必须在“设置”中启用这些语言的输入。然后按下键盘上的地球按钮将在这些语言之间切换。

【讨论】:

  • 嗨,那么,即使使用最新的 SDK,我也不能以编程方式将键盘语言更改为不同的语言?如果需要在我的应用程序中显示键盘,我可以只显示英文键盘吗?能否请您提供任何苹果链接说这是不可能的,所以我可以更清楚地阅读它,非常感谢。
  • 我看到 iPhone 的键盘设置中有一个“添加新键盘..”选项。我们甚至不能通过我们的程序或 iTunes 同步将我们自己的语言文件安装到其中吗?
  • 是的,我们不能插入自己的语言
  • 也许在 2012 年是不可能的。现在通过覆盖textInputMode 是可能的。请参阅 kotvaska 答案。它甚至适用于 ios 11 :)
  • 在 2012 年这是不可能的。通过覆盖 textInputMode 后它成为可能。然而,截至 2019 年 9 月,iOS 13 textInputMode 的返回值被忽略。
【解决方案4】:

声明:

@IBOutlet var yourTextField:cTextField!;

用途:

yourTextField.languageCode = "ru";

类 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;
    }
}

【讨论】:

  • 这可行,但我不能使用它,因为我必须将所有 UITextField 更改为新的 cTextField。我想要对现有 UITextField 进行一些扩展
【解决方案5】:

所有很好的答案。但在 Swift 中,您可以在扩展中覆盖父类 (UIResponder) 中定义的方法和变量。所以没有必要子类化。并且很高兴将 for 循环替换为更快速的单线。

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

可能会用Utils.currentAppLanguage 代替“表情符号”

【讨论】:

    【解决方案6】:

    Swift 5 实施:

    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
        }
    }
    

    【讨论】:

    • 我使用了这个解决方案,但没有工作。我的应用程序有十进制类型的键盘来输入浮点值,当我选择英语时它工作正常并显示小数点但是每当我选择德语或法语时,小数点应该更改为逗号,但即使我将 textInputMode 设置为德语或也不会发生这种情况法语。
    • 此外,如果我杀死了我的应用程序并重新启动,那么小数点将反映为逗号。不知道这是什么问题。
    【解决方案7】:

    这似乎可以改变,例如,希腊键盘:

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

    【讨论】:

    • 这还能用吗?我正在尝试使用 iOS 7,它似乎没有改变键盘,它仍然是英文。
    猜你喜欢
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2018-12-15
    • 2011-03-19
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    相关资源
    最近更新 更多