Ios 使UITextfield仅接受片假名字符-swift

Ios 使UITextfield仅接受片假名字符-swift,ios,swift,uitextfield,Ios,Swift,Uitextfield,我希望我的UITextField只接受一个字符,并且它应该是片假名字符。当用户使用日文罗马字语音键盘打字时,我该如何操作 常规->键盘->键盘->日文罗马书 以下代码不起作用,因为我将英文字符添加到stringparam。似乎我必须处理textfield的markedtextange属性,但不确定如何处理。你知道如何修改下面的方法来满足我的要求吗 当语言为表意文字,键盘为语音时,需要多级文本输入 根据我的观察,markedtextange在调用shouldChangeCharactersInRa

我希望我的UITextField只接受一个字符,并且它应该是片假名字符。当用户使用
日文罗马字
语音键盘打字时,我该如何操作

常规->键盘->键盘->日文罗马书

以下代码不起作用,因为我将英文字符添加到
string
param。似乎我必须处理textfield的
markedtextange
属性,但不确定如何处理。你知道如何修改下面的方法来满足我的要求吗

当语言为表意文字,键盘为语音时,需要多级文本输入


根据我的观察,
markedtextange
在调用
shouldChangeCharactersInRange
之后才会更新。假设我输入一个
s
,首先调用
shouldChangeCharactersInRange
,然后更新
markedTextRange
。这意味着很难区分“在英文键盘上输入第一个”和“在罗马字键盘上输入第一个”,前者是我们不允许的。在这两种情况下,
标记的扩展项
应更改字符范围
中均为零

因此,我认为如果您在
editingChanged
上执行此操作会更容易:

textfield.addTarget(self, action: #selector(textFieldChanged), for: .editingChanged)

...

let katakanas =
    "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン"
@objc func textFieldChanged() {
    let newString = textfield.text ?? ""
    if !(newString.count == 1 &&
            katakanas.contains(newString.first!)) && textfield.markedTextRange == nil {
        // perhaps show an error alert here too
        textfield.text = ""
    }
}
只有在文本更改和更新
markedtextange
后才会调用此函数,因此
textfield.markedtextange==nil
检查将正常工作。如果用户输入了无效的内容,将整个文本字段设置为空应该不会太糟糕,因为您只想接受一个字符

您仍然可以使用
shouldChangeCharactersInRange
来防止用户在已经有一个片假名后输入更多字母:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if let firstChar = textField.text?.first,
       katakanas.contains(firstChar) && string != "" {
        return false
    }
    return true
}

谢谢你的回答。我使用textFieldChanged()函数进行了测试。当我用英文键盘键入
a
时,
textfield.markedtextange
为零,因此
textfield.text=”“
按预期调用@S.Basnagoda
textFieldChanged
仅当您从选项列表中选择一个选项(取消标记时)时才会调用。如果你真的选择了あ 从键盘顶部的选项あ 将会消失。你必须允许あ 作为“标记文本”输入文本字段,否则您将如何键入ア 没有あ? 我的回答是不允许未标记的非片假名。我注意到您没有将所有片假名都包括在列表中,例如带有゛ 及゜, 还有小版本的ヤ,ユ,ヨ,ツ (即。ャ,ュ,ョ,ッ) 这是故意的吗?我从我的客户那里得到了字符列表,我们在我们的应用程序中使用它们作为一个非常具体的绘图功能。所以我希望我们不需要考虑小版本。谢谢你们注意到。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if let firstChar = textField.text?.first,
       katakanas.contains(firstChar) && string != "" {
        return false
    }
    return true
}