I have a form with textfields, an image and a textview. The user can press the 'Post' button only when everything is filled, to validate it, I check if the image is empty, if the textfields are empty and if the textview is empty. The problem is, it doesn't work properly, the button is becoming enabled even when some of the textfields are empty.
This is my validation code:
@objc public func validatePost() {
for ingredient in ingredients {
guard
let _ = ingredient.name,
let _ = ingredient.amount
else {
postButton.isEnabled = false
return
}
}
guard
let title = titleField.text, !title.trimmingCharacters(in: .whitespaces).isEmpty,
let category = categoryField.text, !category.trimmingCharacters(in: .whitespaces).isEmpty,
let _ = postImage.image,
let desc = descriptionField.text, !desc.trimmingCharacters(in: .whitespaces).isEmpty, !desc.trimmingCharacters(in: .newlines).isEmpty
else {
postButton.isEnabled = false
return
}
postButton.isEnabled = true
}
I call this selector when my textfields change, when the user picks an image, and when the textview change.
Textfields:
private lazy var ingredientNameField:UITextField = {
let textField = UITextField()
...
textField.addTarget(CreateFormViewController(), action: #selector(CreateFormViewController.validatePost), for: .editingChanged)
...
return textField
}()
private lazy var ingredientAmountField:UITextField = {
let textField = UITextField()
...
textField.addTarget(CreateFormViewController(), action: #selector(CreateFormViewController.validatePost), for: .editingChanged)
...
return textField
}()
Textview:
func textViewDidChange(_ textView: UITextView) {
validatePost()
}
Image:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[.editedImage] as? UIImage else {
print("No image found")
return
}
postImage.isHidden = false
postImage.image = image
validatePost()
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!){
self.dismiss(animated: true, completion:nil)
guard let image = image else {return}
postImage.isHidden = false
postImage.image = image
validatePost()
}
The bug happens also when I write something in the textview, it shows the button is enabled, then I delete everything inside the textview, and it still shows the button is enabled.
Is my validation incorrect? Thanks.
CodePudding user response:
Okay after a while, I managed to fix that, the reason it happened was because I thought my text is nil while it really was just an empty string. So after adding extra validating to make sure to check for the empty case as well, I managed to get it to work perfectly fine.
CodePudding user response:
Try move this code textField.addTarget(CreateFormViewController(), action: #selector(CreateFormViewController.validatePost), for: .editingChanged)
into viewDidLoad()
func like that:
textField.addTarget(self, action: #selector(validatePost), for: .editingChanged
)
Another way, you can follow these steps:
- Disable button when viewLoaded
- Create listener that's enabled/disabled button when
NotificationCenter
has post a message (valid/invalid) - When your form is valid/invalid, then post a message by
NotificationCenter
.
Read more: https://developer.apple.com/documentation/combine/receiving-and-handling-events-with-combine