【问题标题】:How to set multiple condition for UITextField in shouldChangeCharactersIn in Swift3 iOS如何在 Swift3 iOS 中的 shouldChangeCharactersIn 中为 UITextField 设置多个条件
【发布时间】:2018-10-24 00:16:52
【问题描述】:

我正在创建一个测验类型的应用程序。用户需要在UITextField 中提供输入。所以我必须检查以下条件:

  1. 限制用户只能使用数字和 $ (Like "0123456789$")。

  2. 在文本字段中添加逗号。

  3. $ 应该只在文本字段值中出现一次,并且在任何数字之后也是如此。这意味着用户无法从$开始输入。

  4. $之后,如果用户输入任何数字,那么我必须显示“数字格式不正确”这样的弹出窗口。

这是我的代码:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{


//Solution for 1st condition

let inverseSet = NSCharacterSet(charactersIn:"0123456789$").inverted

        let components = string.components(separatedBy: inverseSet)

        let filtered = components.joined(separator: "")

        if filtered == string {
            return true
        } else {
            if string == "." {
                let countdots = textField.text!.components(separatedBy:".").count - 1
                if countdots == 0 {
                    return true
                }else{
                    if countdots > 0 && string == "." {
                        return false
                    } else {
                        return true
                    }
                }
            }else{
                return false
            }
        }
    }



//Solution for 2nd condition

        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.locale = Locale.current
        formatter.maximumFractionDigits = 0


        if let groupingSeparator = formatter.groupingSeparator {

            if string == groupingSeparator {
                return true
            }


            if let textWithoutGroupingSeparator = textField.text?.replacingOccurrences(of: groupingSeparator, with: "") {
                var totalTextWithoutGroupingSeparators = textWithoutGroupingSeparator + string
                if string == "" { // pressed Backspace key
                    totalTextWithoutGroupingSeparators.characters.removeLast()
                }
                if let numberWithoutGroupingSeparator = formatter.number(from: totalTextWithoutGroupingSeparators),
                    let formattedText = formatter.string(from: numberWithoutGroupingSeparator) {

                    textField.text = formattedText
                    return false
                }
            }
        }
        return true
    }

}

如何在UITextField shouldChangeCharactersIn 方法中设置多个条件。请帮助我实现这一目标。谢谢!

【问题讨论】:

    标签: ios swift3 uitextfield


    【解决方案1】:

    我无法理解您的第二点,但其余的事情可以通过使用简单的正则表达式轻松实现。这是一个例子:

    private func regexMatch(string: String, pattern: String) -> Bool {
        if let range = string.range(of: pattern, options: .regularExpression) {
            let subString = string[range]
            if subString == string {
                return  true
            }
        }
    
        return false
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let result = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
        if regexMatch(string: result, pattern: "[0-9]+\\$*[0-9]*") || result.count == 0 {
            if regexMatch(string: result, pattern: "[0-9]+\\${0,1}") == false && result.count != 0 {
                print("Number format is incorrect")
            }
            return true
        } else {
            return false
        }
    }
    

    此代码 sn-p 将只接受数字和“$”作为 UITextField 的输入。 '$' 不能是第一个字符,'$' 之后的任何数字都会导致打印错误消息。

    我希望这会给您足够的清晰度来定制它以满足您的需求。

    更新:

    限制用户在 '$' 之后输入任何内容并强制只出现一次 '$' 替换

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
    

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let result = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
        if regexMatch(string: result, pattern: "[0-9]+\\${0,1}") || result.count == 0 {
            return true
        } else {
            return false
        }
    }
    

    【讨论】:

    • 感谢您的回复,我现在尝试了您的代码'$'不能是第一个字符和'$'之后的任何数字,但是如何防止用户在$之后不输入任何数字?跨度>
    • 用户只能使用 $ 一次,请帮助我。
    • 我认为,但我最初的答案是基于您在问题中提到的要求。无论如何,我已经更新了我的答案以包含您的观点。
    【解决方案2】:

    最好创建2个验证方法,从两个条件中返回真/假,然后检查两个真与否,然后只让它继续或给出正确的消息。

    func validationCase1(text:String) -> Bool {
     // validate scenario 1.
     return isValidated.
    }
    
    func validateCase2(text:String) -> Bool {
     // validate scenario 2.
     return isValidated.
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
     var isValidatedFirst = validateCase1(string);
     var isValidatedSecond = validateCase2(string);
    
     if(isValidatedFirst == isValidatedSecond == true){
      // pass
     }
     else if(isValidatedFirst == false){
      // show message for first
     }
     else if(isValidatedSecond == false){
      // show message for second
     }
    }
    

    【讨论】:

    • 我必须在 shouldChangeCharactersIn 方法中返回什么?
    • 有没有其他方法可以将此行代码'if(isValidatedFirst == isValidatedSecond == true){'写成错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多