Ios 使用textViewDidChange限制UITextView中的字符

Ios 使用textViewDidChange限制UITextView中的字符,ios,swift,uikit,Ios,Swift,Uikit,我想将输入UITextView的内容限制为双倍,每个双倍由一个空格分隔。当然,这意味着只允许一个小数点 以下代码删除字母和符号,但不适用于小数。输入小数点后,键入的下一个字符将删除该小数点 我做错了什么 import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet weak var dataInputField: UITextView! var currentEntry

我想将输入UITextView的内容限制为双倍,每个双倍由一个空格分隔。当然,这意味着只允许一个小数点

以下代码删除字母和符号,但不适用于小数。输入小数点后,键入的下一个字符将删除该小数点

我做错了什么

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var dataInputField: UITextView!

    var currentEntryHasDecimalPoint:Bool = false
    var validChars: Set<Character> = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", " "]


    override func viewDidLoad() {
        super.viewDidLoad()
        dataInputField.delegate = self
    }


    func textViewDidChange(_ textView: UITextView ) {

        if let str = dataInputField.text, !str.isEmpty {

            let validChar:Bool = Set(str).isSubset(of: validChars)
            if validChar {

                let newChar = str.last!
                switch newChar {
                case ".":
                    currentEntryHasDecimalPoint = true
                    validChars.remove(".")
                case " ":
                    currentEntryHasDecimalPoint = false
                    validChars.insert(".")

                default:
                    print("default")
                }
            }

            else {
                dataInputField.deleteBackward()
            }
        }
    }

}
导入UIKit
类ViewController:UIViewController、UITextViewDelegate{
@IBOutlet弱var数据输入字段:UITextView!
var currentEntryHasDecimalPoint:Bool=false
var validChars:Set=[“0”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“3”、“4”]
重写func viewDidLoad(){
super.viewDidLoad()
dataInputField.delegate=self
}
func textViewDidChange(textView:UITextView){
如果让str=dataInputField.text,!str.isEmpty{
让validChar:Bool=Set(str).isSubset(of:validChars)
如果有效{
让newChar=str.last!
开关newChar{
案例“.”:
currentEntryHasDecimalPoint=true
有效刻线。删除(“.”)
案例“”:
currentEntryHasDecimalPoint=false
有效卡片插入(“.”)
违约:
打印(“默认”)
}
}
否则{
dataInputField.deleteBackward()
}
}
}
}
由于
deleteBackward()
确实更改了
textView
,因此它也会触发
textViewDidChange
。由于当您输入
后接字母时,已从
有效卡片中删除,
”,字母将被删除,并触发
文本视图更改
,然后
将被删除。您应该使用正则表达式
/^(?[0-9]+(?:\.$\.$.[0-9]+)(?:\s+\s*$)+$/
来验证文本,而不是使用
操作

func textViewDidChange(_ textView: UITextView ) {

    if let str = textView.text,
        !str.isEmpty,
        let regex = try? NSRegularExpression(pattern: "^(?:[0-9]+(?:\\.$|\\.[0-9]+)?(?:\\s+|\\s*$))+$", options: []),
        regex.numberOfMatches(in: str, options: [], range: NSRange(location: 0, length: str.count)) == 0
    {
        textView.deleteBackward()
    }
}

您假设用户只是键入单个字符。如果他们复制粘贴会发生什么?此外,这将有一个相当恼人的影响,用户键入一个字符,只有它被删除。您最好查看textView(shouldChangetextIn:replacementText:)。作为一种风格,textViewDidChange已经将textView作为一个参数传递,为什么不使用它而不是类字段成员呢?我建议您使用
textView(\uuu:shouldChangeTextIn:replacementText:)
而不是
textViewDidChange
来复制和粘贴它,只是想弄清楚这一点。删除令人不快的角色的速度如此之快,以至于它似乎只是被忽略了。当在数字列表中键入字母时,用户不应该期望允许使用字母。@Zonly Jame,你能告诉我如何使用它吗?(我对Swift很陌生。)这一点和这一点可以帮助你。这个解决方案在很多情况下都会失败。它不处理用户在文本视图中间粘贴文本。它假设一个字符导致了更改。是的,这只是为了回答为什么会出现“意外”情况以及如何修复它。当然OP应该选择一个完全不同的解决方案。所以,当以编程方式进行更改时,textFieldDidChange不会自动触发,但是textViewDidChange会触发吗?有趣的。。对所有提到它的人来说,这是一个很好的观点,在剪切和粘贴时,什么样的处理方法才是最好的呢?@Ricky Mo,这不起作用。小数根本不会出现。另外,你能给我介绍一个学习如何使用正则表达式的好地方吗?