UITextView 中的每个数字只允许一位小数(Swift 4)

Posted

技术标签:

【中文标题】UITextView 中的每个数字只允许一位小数(Swift 4)【英文标题】:Only allow one decimal for each number in UITextView (Swift 4) 【发布时间】:2020-10-22 20:53:28 【问题描述】:

我有一个UITextView,我在其中输入了一系列以空格分隔的数字(例如:“12.3 30 22.7 19.23 15 8.5 11”)。

UITextView 可能包含多个小数点,但我想确保没有单个数字包含超过一个小数位。

我发现的所有解决方案仅将整个 UITextView 限制为一个小数,而不是每个数字。

我该怎么做?

【问题讨论】:

【参考方案1】:

您可以在 UITextView 委托 func shouldEndEditing.. 中尝试类似的操作。

func textViewShouldEndEditing(_ textView: UITextView) -> Bool 
    guard let numbers = textView.text else 
        return true
    
    var hasMultipleDecimalPlaces: Bool = false
    let numbersAsList = numbers.split(separator: " ")
    for number in numbersAsList 
        let splitAtDecimal = number.split(separator: ".")
        if splitAtDecimal.count > 2 
            if splitAtDecimal[1].count > 2 
                // This is what you want to prevent so break early and return false
                hasMultipleDecimalPlaces = true
                break
            
        
    
    return !hasMultipleDecimalPlaces

这将阻止用户完成对文本视图的编辑。它总是可以用在像shouldReplaceCharactersIn这样的函数中

【讨论】:

【参考方案2】:

我认为您应该使用此委托 textField(_:shouldChangeCharactersIn:replacementString:) 并自行检查每个数字并检查是否已经存在点。并返回 false 或 true。

【讨论】:

【参考方案3】:

在文本视图委托方法中尝试正则表达式:

let regex = try! NSRegularExpression(pattern: "^\\s*((-?)(\\d+\\.?|\\d*\\.\\d+))?(\\s+(-?)(\\d+\\.?|\\d*\\.\\d+))*\\s*$")

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool 
    // Compute the value of the text view after the text is inserted.
    let finalText = (textView.text as NSString).replacingCharacters(in: range, with: text) as NSString
    // Check against a regular expression.
    return regex.firstMatch(in: finalText as String, range: NSRange(location: 0, length: finalText.length)) != nil

您将不得不尝试您想要的行为: https://regex101.com

【讨论】:

【参考方案4】:

最终结果:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool 

    // only allow valid characters
    let validCharacters = " -0123456789.,|\t\n"
    guard CharacterSet(charactersIn: validCharacters).isSuperset(of: CharacterSet(charactersIn: text)) else 
        return false
    
    
    let oldText = txtViewDataInput.text!
    let r = Range(range, in: oldText)
    let text = oldText.replacingCharacters(in: r!, with: text)
    debugPrint("text = \(text)")

    let whiteSpace = " ,|\t\n"
    let separators = NSCharacterSet(charactersIn: whiteSpace)

    let tempArray = text.components(separatedBy: separators as CharacterSet)

    // do not allow more than one decimal point in a number
    for number in tempArray 
        let splitAtDecimal = number.filter  $0 == "." .count
        if splitAtDecimal > 1 
            return false
        
    
    return true

【讨论】:

以上是关于UITextView 中的每个数字只允许一位小数(Swift 4)的主要内容,如果未能解决你的问题,请参考以下文章

十进制一位输入类型仅数字 Ionic 3 最新版本 (3.9.2) 我正在使用

如何在Python中保留小数?

input只允许输入数字和小数

flutter TextField 限制只允许输入数字 小数点

计算钱时一定要保留两位小数吗

flutter TextField 限制只允许输入数字 小数点