警报控制器内多个文本字段的空文本验证

Empty text validation on multiple textfields inside alert controller

这是我的 ui 警报控制器。如果任何文本字段为空,我需要禁用提交按钮。目前我有一种方法可以验证单个文本字段,但我似乎无法弄清楚如何将它应用于所有文本字段。这是我的警报控制器和文本字段:

  let ac = UIAlertController(title: "Enter Custom Specifications", message: nil, preferredStyle: .alert)
    ac.addTextField { (textField : UITextField!) -> Void in
        textField.placeholder = "Material Name"
        textField.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: .editingChanged)
    }

    ac.addTextField { (textField : UITextField!) -> Void in
        textField.placeholder = ""
        textField.keyboardType = UIKeyboardType.decimalPad
    }

    ac.addTextField { (textField : UITextField!) -> Void in
        textField.placeholder = ""
        textField.keyboardType = UIKeyboardType.decimalPad
    }

    ac.addTextField { (textField : UITextField!) -> Void in
        textField.placeholder = ""
        textField.keyboardType = UIKeyboardType.decimalPad
    }

使用在上面第一个文本字段中调用的这个函数,我可以获得每个文本字段的正确空字符串验证,这意味着当第一个文本字段为空时提交被禁用,但是当我开始输入时提交被启用。如果我将函数调用放在每个文本字段声明中,每个文本字段都会出现相同的行为。

 @objc func textFieldDidChange(textField: UITextField){
    if textField.text == "" {

        submitAction.isEnabled = false
    }
    else
    {
        submitAction.isEnabled = true

    }

}

我需要一种方法来同时检查所有文本字段,如果其中任何一个为空,则禁用提交。

编辑:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField.text == "" {
        //You can perfrom your activity here when textfield got blank or empty
        submitAction.isEnabled = false
    }
    else if textField.text != ""
    {
        submitAction.isEnabled = true
        //You can perfrom your activity here when textfield got not blank or not empty
    }
    //add your code here...
    return true
}

编辑 2:

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

    if let text = (textField.text as? NSString)?.replacingCharacters(in: range, with: string), !text.isEmpty {
        if let text = textField.text?.replacingCharacters(in: range, with: string), !text.isEmpty {
            submitAction.isEnabled = true
        } else {
            submitAction.isEnabled = false
        }
        return true
    }}

编辑 3: 我可以在创建它们时将它们命名为 textfield"x",而不是只调用 "textfield":

ac.addTextField { (textField2 : UITextField!) -> Void in
        textField2.placeholder = "Column Width (in)"
        textField2.keyboardType = UIKeyboardType.decimalPad
        textField2.delegate = self
    }

如何让 shouldChangeCharactersIn 同时接受它们?

编辑(解决方案):

好的,我明白了。 PGD​​ev 在逻辑部分是正确的,但用于实际检查的委托函数却不正确。我要把他的回答标记为正确,因为没有它我就不会走到这一步。

最初我们使用的是 textFieldDidEndEditing,我认为它根本不起作用,因为一旦所有四个文本字段都被填充,它就不会重新启用提交按钮。我没有意识到的是,在完成调用 textFieldDidEndEditing 之后,我必须点击一个额外的文本字段。有道理,因为它的名称中有 "EndEditing"。

我采用了 PGDevs 逻辑并将其放入 shouldChangeCharactersIn 中,但效果不佳。我不确定它是否存在内部问题,但是当您尝试填充最后一个文本框时,有时退格键(或其他内容)被解释为一个字符并且它会抛出 enable / !enable 语句。

使用 PGDevs 逻辑的 textFieldDidChange 就是答案。

为要添加到警报控制器的文本框数量设置 class 宽变量:

var textField1: UITextField?
var textField2: UITextField?
var textField3: UITextField?
var textField4: UITextField?

将此函数放在 class 函数的底部:

   @objc func textFieldDidChange(_ textField: UITextField) {

    let text1 = self.textField1?.text ?? ""
    let text2 = self.textField2?.text ?? ""
    let text3 = self.textField3?.text ?? ""
    let text4 = self.textField4?.text ?? ""

    if !text1.isEmpty && !text2.isEmpty && !text3.isEmpty && !text4.isEmpty {
        submitAction.isEnabled = true
    } else {
        submitAction.isEnabled = false
    }

}

当您在警报控制器中生成一个实际的文本字段时,调用上面的函数:

 let ac = UIAlertController(title: "Enter Custom Specifications", message: nil, preferredStyle: .alert)
    ac.popoverPresentationController?.sourceView = self.view
    ac.addTextField { (textField : UITextField!) -> Void in
        textField.delegate = self
        textField.placeholder = "Material Name"
        self.textField1 = textField
        textField.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged)
    }

这非常适合我。除非所有 4 行中至少有一个字符,否则提交将保持禁用状态。这可以用于任意数量的文本字段。

尝试将每个 textField 的委托设置为显示警报的 viewCobtroller,即

textField.delegate = self

遵循 ViewController UITextFieldDelegate 协议,

class ViewController: UIViewController, UITextFieldDelegate {

实现相关的UITextFieldDelegate方法,示例:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if let text = (textField.text as? NSString)?.replacingCharacters(in: range, with: string), !text.isEmpty {
        submitAction.isEnabled = true
    } else {
        submitAction.isEnabled = false
    }
    return true
}

编辑:

您需要将 reference 保留在所有 textFields 中,以便您可以检查所有 textenable/disablesubmitAction,即

var textField1: UITextField?
var textField2: UITextField?
var textField3: UITextField?
var textField4: UITextField?

在添加到 UIAlertController 的同时设置每个 textFields,即

let ac = UIAlertController(title: "Enter Custom Specifications", message: nil, preferredStyle: .alert)
ac.addTextField { (textField : UITextField!) -> Void in
    textField.delegate = self
    textField.placeholder = "Material Name"
    self.textField1 = textField
}
ac.addTextField { (textField : UITextField!) -> Void in
    textField.delegate = self
    textField.keyboardType = UIKeyboardType.decimalPad
    self.textField2 = textField
}
ac.addTextField { (textField : UITextField!) -> Void in
    textField.delegate = self
    textField.keyboardType = UIKeyboardType.decimalPad
    self.textField3 = textField
}
ac.addTextField { (textField : UITextField!) -> Void in
    textField.delegate = self
    textField.keyboardType = UIKeyboardType.decimalPad
    self.textField4 = textField
}

每当 textFields 中的任何一个发生变化时调用 validate(),即

func textFieldDidEndEditing(_ textField: UITextField) {
    self.validate()
}


func validate() {
    let text1 = self.textField1?.text ?? ""
    let text2 = self.textField2?.text ?? ""
    let text3 = self.textField3?.text ?? ""
    let text4 = self.textField4?.text ?? ""

    if !text1.isEmpty && !text2.isEmpty && !text3.isEmpty && !text4.isEmpty {
        submitAction.isEnabled = true
    } else {
        submitAction.isEnabled = false
    }
}