只有在所有文本字段都被填写的情况下才能在Swift中启用button

我无法弄清楚如何改变我的代码,使我的三个文本字段填写时导航栏中的完成button被启用。

我目前有三个UITextFields和一个UIButtonItem。 habitNameField和goalField都是手动文本字段,而frequencyField是拾取器视图。

@IBOutlet weak var habitNameField: UITextField! @IBOutlet weak var goalField: UITextField! @IBOutlet weak var frequencyField: UITextField! @IBOutlet weak var doneBarButton: UIBarButtonItem! 

当第一个字段中input某些内容时,我也有以下function。

 func textField(habitNameField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let oldHabitNameText: NSString = habitNameField.text! let newHabitNameText: NSString = oldHabitNameText.stringByReplacingCharactersInRange(range, withString: string) doneBarButton.enabled = (newHabitNameText.length != 0) return true } 

我试着改变代码,以便在其他两个字段中作为参数,并且只有在填写完所有三个字段的情况下才启用doneBarButton。

 func textField(habitNameField: UITextField, goalField: UITextField, frequencyField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let habitNameText: NSString = (habitNameField.text!).stringByReplacingCharactersInRange(range, withString: string) let goalText: NSString = (goalField.text!).stringByReplacingCharactersInRange(range, withString: string) let frequencyText: NSString = (frequencyField.text!).stringByReplacingCharactersInRange(range, withString: string) doneBarButton.enabled = (habitNameText.length != 0) && (goalText.length != 0) && (frequencyText.length != 0) return true } 

但是,即使填写了全部三个文本字段,它也不起作用。

我真的很感激任何帮助,并感谢所有提前做出贡献的人!

所有代码在这里:

 class HabitDetailViewController: UITableViewController, UITextFieldDelegate, UIPickerViewDataSource,UIPickerViewDelegate { @IBOutlet weak var habitNameField: UITextField! @IBOutlet weak var goalField: UITextField! @IBOutlet weak var doneBarButton: UIBarButtonItem! @IBOutlet weak var frequencyField: UITextField! var frequencies = ["Day", "Week", "Month", "Year"] var frequencyPicker = UIPickerView() var habitToEdit: HabitItem? weak var delegate: HabitDetailViewControllerDelegate? @IBAction func cancel() { delegate?.habitDetailViewControllerDidCancel(self) } @IBAction func done() { print("You plan to do \(habitNameField.text!) \(goalField.text!) times a \(frequencyField.text!.lowercaseString).") if let habit = habitToEdit { habit.name = habitNameField.text! habit.numberLeft = Int(goalField.text!)! habit.frequency = frequencyField.text! delegate?.habitDetailViewController(self, didFinishEditingHabit: habit) } else { let habit = HabitItem() habit.name = habitNameField.text! habit.numberLeft = Int(goalField.text!)! habit.frequency = frequencyField.text! habit.completed = false delegate?.habitDetailViewController(self, didFinishAddingHabit: habit) } } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) habitNameField.becomeFirstResponder() frequencyPicker.hidden = false } override func viewDidLoad() { super.viewDidLoad() frequencyPicker.dataSource = self frequencyPicker.delegate = self doneBarButton.enabled = false habitNameField.addTarget(self, action: "checkFields:", forControlEvents: .EditingChanged) goalField.addTarget(self, action: "checkFields:", forControlEvents: .EditingChanged) frequencyField.addTarget(self, action: "checkFields:", forControlEvents: .EditingChanged) frequencyField.inputView = frequencyPicker if let habit = habitToEdit { title = "Edit Item" habitNameField.text = habit.name goalField.text = String(habit.numberLeft) doneBarButton.enabled = true } } override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { return nil } func textField(habitNameField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let oldHabitNameText: NSString = habitNameField.text! let newHabitNameText: NSString = oldHabitNameText.stringByReplacingCharactersInRange(range, withString: string) doneBarButton.enabled = (newHabitNameText.length != 0) return true } func checkFields(sender: UITextField) { sender.text = sender.text?.stringByTrimmingCharactersInSet(.whitespaceCharacterSet()) guard let habit = habitNameField.text where !habit.isEmpty, let goal = goalField.text where !goal.isEmpty, let frequency = frequencyField.text where !frequency.isEmpty else { return } // enable your button if all conditions are met doneBarButton.enabled = true } 

Xcode 8.3.2•Swift 3.1

你可以添加目标到你的文本字段来监视控制事件.editingChanged并使用一个单一的select器方法为他们所有:

 override func viewDidLoad() { super.viewDidLoad() doneBarButton.isEnabled = false habitNameField.addTarget(self, action: #selector(editingChanged), for: .editingChanged) goalField.addTarget(self, action: #selector(editingChanged), for: .editingChanged) frequencyField.addTarget(self, action: #selector(editingChanged), for: .editingChanged) } 

创buildselect器的方法,并使用guard结合where子句(Swift 3使用逗号),以确保所有文本字段不是空的,否则只是返回:

 func editingChanged(_ textField: UITextField) { if textField.text?.characters.count == 1 { if textField.text?.characters.first == " " { textField.text = "" return } } guard let habit = habitNameField.text, !habit.isEmpty, let goal = goalField.text, !goal.isEmpty, let frequency = frequencyField.text, !frequency.isEmpty else { doneBarButton.isEnabled = false return } doneBarButton.isEnabled = true } 

样品

Swift 3 / Xcode 8.2

在这里输入图像说明

 override func viewDidLoad() { super.viewDidLoad() setupAddTargetIsNotEmptyTextFields() } func setupAddTargetIsNotEmptyTextFields() { okButton.isHidden = true //hidden okButton nameUserTextField.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged) emailUserTextField.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged) passwordUserTextField.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged) confimPasswordUserTextField.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged) } 

然后创buildselect器方法并使用guard

 @objc func textFieldsIsNotEmpty(sender: UITextField) { sender.text = sender.text?.trimmingCharacters(in: .whitespaces) guard let name = nameUserTextField.text, !name.isEmpty, let email = emailUserTextField.text, !email.isEmpty, let password = passwordUserTextField.text, !password.isEmpty, let confirmPassword = confimPasswordUserTextField.text, password == confirmPassword else { self.okButton.isHidden = true return } // enable okButton if all conditions are met okButton.isHidden = false } 

PS在swift 3“ where ”== >>>“

最好的方法是在ViewDidLoad方法中添加观察者。 比只检查textField委托方法是否所有的TextFields是否被填满。 一旦它填补了呼吁oberserver方法&在那你只需要启用button。

注意:

  • 您可以使用观察者来启用或禁用button

希望它会帮助你。

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if (textField == self.textField1) { /* do Something */ } else if (textField == self.textField2) { /* do Something */ } else if (textField == self.textField3) { /* do Something */ } // regardless of what you do before, doneBarButton is enabled when all are not empty doneBarButton.enabled = (textField1.length != 0) && (textField2.length != 0) && (textField3.length != 0) return true 

}

为什么不把检查function移动到一个单独的function

 func setDoneButtonStatus() { let habitNameText: NSString = (habitNameField.text!).stringByReplacingCharactersInRange(range, withString: string) let goalText: NSString = (goalField.text!).stringByReplacingCharactersInRange(range, withString: string) let frequencyText: NSString = (frequencyField.text!).stringByReplacingCharactersInRange(range, withString: string) doneBarButton.enabled = (habitNameText.length != 0) && (goalText.length != 0) && (frequencyText.length != 0) } 

然后使用

 func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() setDoneButtonStatus() } 

这对我有用:希望它有帮助

  func textFieldDidEndEditing(textField: UITextField) { if txtField1.hasText() && textField2.hasText() && textField3.hasText(){ doneBarButton.enabled = true } } 

我继续前进,把它抽象成一个可以用于快速项目的助手类。

 import Foundation import UIKit class ButtonValidationHelper { var textFields: [UITextField]! var buttons: [UIButton]! init(textFields: [UITextField], buttons: [UIButton]) { self.textFields = textFields self.buttons = buttons attachTargetsToTextFields() disableButtons() checkForEmptyFields() } //Attach editing changed listeners to all textfields passed in private func attachTargetsToTextFields() { for textfield in textFields{ textfield.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged) } } @objc private func textFieldsIsNotEmpty(sender: UITextField) { sender.text = sender.text?.trimmingCharacters(in: .whitespaces) checkForEmptyFields() } //Returns true if the field is empty, false if it not private func checkForEmptyFields() { for textField in textFields{ guard let textFieldVar = textField.text, !textFieldVar.isEmpty else { disableButtons() return } } enableButtons() } private func enableButtons() { for button in buttons{ button.isEnabled = true } } private func disableButtons() { for button in buttons{ button.isEnabled = false } } } 

然后在您的视图控制器只是简单地启动助手

 buttonHelper = ButtonValidationHelper(textFields: [textfield1, textfield2, textfield3, textfield4], buttons: [button]) 

确保你在顶部保留一个强大的引用,以防止重新分配

 var buttonHelper: ButtonValidationHelper!