如何实现此功能以在 UITextField 中输入 DOB

Posted

技术标签:

【中文标题】如何实现此功能以在 UITextField 中输入 DOB【英文标题】:How can I achieve this functionality to enter DOB in UITextField 【发布时间】:2020-10-16 17:16:38 【问题描述】:

我使用一个变量来存储输入的文本,并通过附加“mm/dd/yyyy”的剩余后缀来修改它。我正在使用该功能,但是如果我尝试将光标更新到正确的位置,则会产生问题。 我使用 textfield.selectedTextRange 将光标从 EOF 移动到我需要的位置。但是,它正在用“mm/dd/yyyy”中的最后一个“y”替换输入的文本。因此,如果我输入“12”,则文本将从 mm/dd/yyyy| 更改改为“yy|/mm/yyyy”而不是“12|/dd/yyy”

我做错了吗?

let dobPlaceholderText = "mm/dd/yyyy"
var enteredDOBText = ""

@objc func textFieldDidChange(_ textField: UITextField)
    enteredDOBText.append(textField.text.last ?? Character(""))
    let modifiedText = enteredDOBText + dobPlaceholderText.suffix(dobPlaceholderText.count - enteredDOBText.count)
    textField.text = modifiedText
    setCursorPosition(input: dob.textField, position: enteredDOBText.count)

private func setCursorPosition(input: UITextField, position: Int)
    let position = input.position(from: input.beginningOfDocument, offset: position)!
    input.selectedTextRange = input.textRange(from: position, to: position)

【问题讨论】:

我们不知道你是否做错了,因为你没有展示你在做什么。请显示实际代码。比仅仅谈论它要好得多。 对不起@matt。 gif没有立即上传。现在它是。请检查 那么developer.apple.com/documentation/uikit/uitextfielddelegate/…会不会更好? @matt 我只能在文本输入完成后更新文本和修改光标。所以不能使用textField(_:shouldChangeCharactersIn:replacementString:) shouldChangeCharactersIn:replacementString 中你可以得到更新后的文本,如下所示:let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) 【参考方案1】:

cmets 中的 matt 和 aheze 建议使用textField(_:shouldChangeCharactersIn:replacementString:) 在此类用例中非常有前景。

该过程可能如下所示:

确定用户输入后的结果文本,并过滤掉所有非数字字符 应用dobPlaceholderText 中定义的模式 在 UIText 字段中设置结果 确定并设置新的光标位置

在源代码中可能如下所示:

let dobPlaceholderText = "mm/dd/yyyy"
let delims = "/"
let validInput = "0123456789"

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool 
    let filteredText = filtered(textField.text, range: range, replacement: string)
    let newText = applyPattern(filteredText, pattern: Array(dobPlaceholderText))
    textField.text = newText
    let newPosition = newCursorPosition(range: range, replacement: string, newText: newText)
    setCursorPosition(input: textField, position: newPosition)
    return false

filteredapplyPatternnewCursorPosition 这三种方法的实际实现取决于您想要实现的确切细节行为。这只是一个示例实现,请使用反映您要求的内容。

private func filtered(_ text: String?,range:NSRange, replacement: String) -> Array<Character> 
    let textFieldText: NSString = (text ?? "") as NSString
    let textAfterUpdate = textFieldText.replacingCharacters(in: range, with: replacement)
    var filtered = Array(textAfterUpdate.filter(validInput.contains))
    if filtered.count >= dobPlaceholderText.count 
        filtered = Array(filtered[0..<dobPlaceholderText.count])
    
    return filtered


private func applyPattern(_ filtered: Array<Character>, pattern: Array<Character>) -> String 
    var result = pattern
    var iter = filtered.makeIterator()
    
    for i in 0..<pattern.count 
        if delims.contains(pattern[i]) 
            result[i] = pattern[i]
         else if let ch = iter.next() 
            result[i] = ch
         else 
            result[i] = pattern[i]
        
    
    return String(result)


private func newCursorPosition(range: NSRange, replacement: String, newText: String) -> Int 
    var newPos = 0
    if replacement.isEmpty 
        newPos = range.location
    
    else 
        newPos = min(range.location + range.length + 1, dobPlaceholderText.count)
        if newPos < dobPlaceholderText.count && delims.contains(Array(newText)[newPos]) 
            newPos += 1
        
    
    return newPos

演示

【讨论】:

以上是关于如何实现此功能以在 UITextField 中输入 DOB的主要内容,如果未能解决你的问题,请参考以下文章

设置 UITextField 约束以在换行符中继续

如何在 viewDidLoad 上的 Swift 中显示没有 UITextField 的标准数字键盘

设置值后如何在 UITextField 中移动光标

禁用 UITextField 的自动更正

如何实现占位符文本在 UITextField 中逐个字符消失

简单几步实现 IOS UITextField输入长度的控制