只有在所有文本字段都被填写的情况下才能在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!
- Swift 3.0错误:转义闭包只能通过值显式捕获inout参数
- 以每x秒的速度更新一个标签
- 当单元格仍然显示时,UICollectionView中的大单元格被移除
- 如何从下一首歌曲开始,或者在播放AVPlayer的过程中认出一首歌曲已经完成?
- 自定义UITableViewCell与进度条下载更新
- 如何更改UIStoryboard中使用的动态颜色
- App Store的代码与iPhone 3G上的Xcode / Device代码不同
- 具有4个viewControllers的Page Viewtroller – 如何将视图2设置为初始viewController?
- 什么是预处理器macros来testing是否正在构build应用程序扩展?