最大输入后禁用 UITextField 光标移动
Posted
技术标签:
【中文标题】最大输入后禁用 UITextField 光标移动【英文标题】:Disable UITextField cursor movement after max input 【发布时间】:2019-10-14 05:38:29 【问题描述】:我为固定大小的输入创建了一个自定义 UITextField 组件。 TextField 的宽度、字体大小、字距和字符数都是固定的。我可以阻止用户输入超过 8 个字符(参见下面的 shouldChangeCharactersIn 方法),但是在第 8 个字符之后,光标会自动移动到下一个位置,这会产生以下问题。
我想显示所有输入的字符而不减小它们的大小。所以
[ 1 2 3 4 5 6 7 8 ] 应该显示而不是 [ 2 3 4 5 6 7 8 | ]
我试图将光标放在第 8 个字符的右侧,但这会改变所有字距并影响所有其他字符。
处理这个问题的正确方法是什么?我应该如何防止光标移动,以使 UITextField 不会向右滚动?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
guard let textFieldText = textField.text,
let rangeOfTextToReplace = Range(range, in: textFieldText),
!string.containsSpecialCharacters else
return false
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= 8
【问题讨论】:
试试这个guard let currentText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) else return true let newLength = currentText.count + string.count - range.length return newLength <= 8
这会阻止第 8 个字符的输入。我想允许 8 个字符,那么光标不应该移动到下一个空格。
【参考方案1】:
我通过更改最后一个字符后的紧排来解决了这个问题。所以现在,光标不再跳 40pt,而是只跳 1pt(或者你在下面的方法中设置的任何东西)
@objc private func textFieldDidChange()
guard let text = textField.text else return
if text.count == Constant.deviceCodeCharacterCount
let attributedString = NSMutableAttributedString(string: text)
attributedString.addAttribute(.kern, value: Constant.deviceCodeCharacterSpacing, range: NSRange(location: 0, length: text.count - 1))
attributedString.addAttribute(.kern, value: 1, range: NSRange(location: Constant.deviceCodeCharacterCount - 1, length: 1))
textField.attributedText = attributedString
【讨论】:
【参考方案2】:试试下面的代码:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if textField.text?.count ?? 0 <= 7
if textField.text?.count ?? 0 == 7
DispatchQueue.main.async
textField.resignFirstResponder()
return true
textField.resignFirstResponder()
return false
在 viewController 的 viewDidLoad
方法中将 customTextField 的委托设置为 self,并确认 UITextFieldDelegate
协议
【讨论】:
这只是隐藏了键盘,这不是预期的行为。我只是想防止光标在最后一个字符后跳转。用户仍然可以尝试输入更多或删除字符。【参考方案3】:如果您尝试此代码会发生什么?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if range.location < 8
return true
// return NO to not change text
return false
【讨论】:
以上是关于最大输入后禁用 UITextField 光标移动的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 中的 UItextfield 并用放大镜移动光标