1

I have two textFields and a TableView. The Tableview should initially be disabled (meaning the labels greyed out and the cells are not clickable). When both textFields have values, I want the TableView and the tableViewCells to be clickable and not greyed out. So far, I've added targets to both of the textfields to track when the user is editing:

var isUserEditing: Bool = false

func setup() {
        mealItemTextField.addTarget(self, action: #selector(userIsEditing), for: UIControl.Event.editingChanged)
        priceTextField.addTarget(self, action: #selector(userIsEditing), for: UIControl.Event.editingChanged)
    }

@objc func userIsEditing(sender: UITextField) {
        sender.text = sender.text?.trimmingCharacters(in: .whitespaces)
        guard
            let mealtext = mealItemTextField.text, !mealtext.isEmpty,
            let pricetext = priceTextField.text, !pricetext.isEmpty
        else
        {
            isUserEditing = false
            return
        }
        isUserEditing = true
    }

Then I created an extension for UITableViewCell that basically "enables" and "disables" the tableView (retrieved from this thread):

  extension UITableViewCell {
    func enable(on: Bool) {
        for view in contentView.subviews {
            view.isUserInteractionEnabled = on
            view.alpha = on ? 1 : 0.5
        }
    }
}

Finally, I implemented this method as well as the variable isUserEditing in my viewForHeaderInSection:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let userModel = Data.userModels[section]
    let cell = tableView.dequeueReusableCell(withIdentifier: "nameCell") as! NameHeaderTableViewCell
    cell.setup(model: userModel)
    cell.enable(on: false)
    if isUserEditing == true {
        cell.enable(on: true)
    }
    return cell.contentView
}

The tableView appears "disabled" when the view loads, however when I start typing in one or both of the textFields, it remains disabled. So obviously the viewForHeaderInSection isn't reloading, or being executed again.

Is there any way to achieve this? Can I run the viewForHeaderInSection in realtime and update automatically? Any help is appreciated, thanks!

This should be the initial view when there is no text in the textField

This should be the view after there is some text in both textFields

joker449
  • 109
  • 1
  • 9

2 Answers2

5

tableView.reloadData() is missing due to which table view is not getting reloaded.

@objc func userIsEditing(sender: UITextField) {
       sender.text = sender.text?.trimmingCharacters(in: .whitespaces)
       guard
           let mealtext = mealItemTextField.text, !mealtext.isEmpty,
           let pricetext = priceTextField.text, !pricetext.isEmpty
       else
       {
           isUserEditing = false
       tableView.reloadData() // reload table view here
           return
       }
       isUserEditing = true
    tableView.reloadData() // reload table view here
   }
Aman
  • 241
  • 2
  • 10
1

If you want to enable your tableView as keyboard appeared and textfields are empty or not you can check this by notifications;

in your ViewController class:

        override func viewDidLoad() {
             super.viewDidLoad()
             yourTableView.isUserInteractionEnabled = false

         // check notifications if keyboard shown or not
            NotificationCenter.default.addObserver(self, selector: #selector(showKeyboard), name: UIResponder.keyboardWillShowNotification, object: nil)     
            NotificationCenter.default.addObserver(self, selector: #selector(hideKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)

         // if your textFields out of your tableview
              yourTextField1.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
                yourTextField2.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

                }


 @objc func textFieldDidChange(textField: UITextField){

     self.yourTableView.isUserInteractionEnabled = true
     print("Text changed")

  }

  // show keyboard function
  @objc func showKeyboard(notification: NSNotification){

  // You can disable your tableview or your cells in this case i just disable tableview.

     yourTableView.isUserInteractionEnabled = true
     print("keyboard appeared")
   }

   // this part is up to how you want to implement. If you want to keep tableview active after textField edited don't use this method

  @objc func hideKeyboard(notification: NSNotification){

   // You can disable your tableview or your cells
      yourTableView.isUserInteractionEnabled = false
      print("keyboard disappeared")
   }

   func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   let userModel = Data.userModels[section]
   let cell = tableView.dequeueReusableCell(withIdentifier: "nameCell") as! NameHeaderTableViewCell

        // if your text Fields inside tableView tracking you textfield changes (in this case you couldn't disable tableView initially) 

   cell.yourTextField1.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
   cell.yourTextField2.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
                return cell.contentView
   }

I hope this will solve your problem good luck.