【问题标题】:How to limit number of decimals in textfield when user input is from pasteboard, iOS Swift当用户输入来自粘贴板时,如何限制文本字段中的小数位数,iOS Swift
【发布时间】:2021-12-28 10:04:54
【问题描述】:

我有一个文本字段,用户只能输入 6 位小数,如果有小数,如果没有,则允许他输入用户想要的任意数量的字符。

例如,我允许这个:7472828282 和这个:0,123456,而不是这个:0,2139213773219312。

我当前的实现对于上面的这个例子和当用户从电子键盘进行输入时是好的,但是当用户粘贴一些值时我无法让它工作,例如用户可以粘贴这个值:0,123456789,但我想在小数点后 6 位后截取,实际上是这样的:0,123456,不,我不需要将它舍入到更大的小数点,我需要截取它!

感谢您的帮助,我目前的代码如下

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField === self.amountView.textField {
    
    guard let text = textField.text, let decimalSeparator = NSLocale.current.decimalSeparator else {
        return true
    }
    
    var splitText = text.components(separatedBy: decimalSeparator)
    let totalDecimalSeparators = splitText.count - 1
    let isEditingEnd = (text.count - 3) < range.lowerBound
    
    splitText.removeFirst()
    
    if  splitText.last?.count ?? 0 > 5 && string.count != 0 && isEditingEnd {
        return false
    }
    
    if totalDecimalSeparators > 0 && string == decimalSeparator {
        return false
    }
}
return true
}

【问题讨论】:

    标签: ios swift decimal textfield uipasteboard


    【解决方案1】:

    此代码始终更新textField 的内容,但限制了小数位数:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        guard let decimalSeparator = NSLocale.current.decimalSeparator else {return true}
    
        // Updates the text
        var updatedText = (textView.text as NSString).replacingCharacters(in: range, with: text) 
    
        // If someone needs to cover all possible decimal separator values, the commented line below is the solution
        // let textComponents = updatedText.components(separatedBy: [",", "."])
    
        let textComponents = updatedText.components(separatedBy: decimalSeparator)
        
        // Truncates the decimals
        if textComponents.count > 1 && textComponents[1].count > 6{
           updatedText = textComponents[0].appending(decimalSeparator).appending((textComponents[1] as NSString).substring(to: 6))
        }
            
        textView.text = updatedText
    
        // The text has already been updated, so returns false
        return false 
    }
    

    【讨论】:

    • 如果答案解释问题和解决方案,而不是仅发布代码,则对问题的作者和本主题的未来读者更有帮助。
    • String 函数 appending(_:) 记录在哪里?我在任何地方都找不到它,甚至 Xcode 中的“跳转到定义”功能也无法向我显示 Foundation 标头中的定义。
    • 谢谢@RedWheelbarrow,您的评论部分有效,但是当我尝试删除我的输入时,我得到的错误是:Thread 1: "*** -[__NSCFString substringToIndex:]: Index 6 out边界;字符串长度 5"
    • @miki 我已经更正了我的答案
    • @DuncanC appending(_:) 在 Foundation.NSString 中定义
    【解决方案2】:

    您的错误:您正在检查旧内容。

    shouldChangeCharacters 为您提供旧文本(仍在文本字段中)、要替换的范围(选择或只是插入点)和替换。如果范围被替换,您首先需要计算新文本,然后然后检查该结果。

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 1970-01-01
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2020-01-28
      • 1970-01-01
      • 2014-08-31
      相关资源
      最近更新 更多