Home > Software design >  Checking for filled text field & textview isn't working properly (UIKit)
Checking for filled text field & textview isn't working properly (UIKit)

Time:05-17

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

  • Related