使 UITextfield 只接受片假名字符 - swift
Posted
技术标签:
【中文标题】使 UITextfield 只接受片假名字符 - swift【英文标题】:Make UITextfield accept only Katakana characters - swift 【发布时间】:2021-05-19 06:03:28 【问题描述】:我希望我的 UITextField 只接受 一个字符,它应该是一个 片假名字符。用户使用Japanese-Romaji
注音键盘打字时怎么办?
General->Keyboard->Keyboards-> Japanese Romaji
以下代码不起作用,因为我将英文字符发送到 string
参数。看来我必须处理 textFiled 的markedTextRange
属性,但不确定如何处理。知道如何修改以下方法以满足我的要求吗?
当语言是表意而键盘是拼音时,需要多级文本输入。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if string.rangeOfCharacter(from: .init(charactersIn: "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン")) != nil || string == ""
return true
else
return false
【问题讨论】:
我注意到您的列表中没有包含所有片假名,例如带有゛和゜的片假名,以及ヤ、yu、ヨ、ツ的小版本(即ャ、ュ、ョ,ッ) 这是故意的吗? 我从我的客户那里得到了上面的字符列表,我们将它们用于我们应用程序中非常具体的绘图功能。所以我希望我们不需要考虑小版本。感谢您注意到????♂️ 【参考方案1】:根据我的观察,markedTextRange
直到调用 shouldChangeCharactersInRange
之后才会更新。假设我输入了一个s
,首先调用shouldChangeCharactersInRange
,然后更新markedTextRange
。这意味着很难区分“在英文键盘上输入第一个's'”和“在罗马字键盘上输入第一个's'”,我们希望禁止前者。在这两种情况下,markedTextRange
在shouldChangeCharactersInRange
中都为零。
因此,我认为如果你在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 = ""
只有在文本更改和markedTextRange
更新后才会调用它,因此textfield.markedTextRange == nil
检查将正常工作。将整个文本字段设置为空白以防用户输入无效的内容,这对 UX 来说应该不算太糟糕,因为无论如何您只打算接受一个字符。
你仍然可以使用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.markedTextRange
为零,因此textfield.text = ""
按预期被调用?。但是当我用罗马字键盘输入a
时,textfield.markedTextRange
不是 nil 并且あ
被插入到 textField 中(这不是片假名)。不知道为什么textfield.markedTextRange
不为零?
@S.Basnagoda 这是预期的。 textFieldChanged
仅在您从选项列表中选择一个选项时调用(当您取消标记时)。如果你真的选择键盘顶部的あ选项,あ会消失。您必须允许将 あ 作为“标记文本”输入到文本字段中,否则您将如何在没有 あ 的情况下键入 ア?我的回答是它不允许未标记的非片假名。以上是关于使 UITextfield 只接受片假名字符 - swift的主要内容,如果未能解决你的问题,请参考以下文章
如何限制 UITextField 在 Swift 中只接受数字?
如何使键盘 UITextField 中的数字视图成为默认值?