如何在Swift3 iOS的shouldChangeCharactersIn中为UITextField设置多个条件

时间:2018-05-14 10:54:13

标签: ios swift3 uitextfield

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

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

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

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

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

  5. 这是我的代码:

    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方法中设置多个条件。请帮我实现这个目标。谢谢!

2 个答案:

答案 0 :(得分:0)

最好创建2个验证方法,从两个条件返回true / false,然后检查是否为true,然后仅使其继续或给出正确的消息。

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
 }
}

答案 1 :(得分:0)

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

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

此代码段仅接受数字和' $'作为UITextField的输入。 ' $'不能是' $'之后的第一个字符和任何数字。将导致打印错误消息。

我希望这会让您足够清晰地定制它以满足您的需求。

<强>更新

限制用户在&#39; $&#39;之后输入任何内容并且只强制执行一次&#39; $&#39;替换

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
    }
}

{{1}}