0

I have a problem with custom tableview cell with a textfield. So, I have a separate class for a cell with a textfield, but I can't retrieve data in my tableview class. There is a delegate for textfield in tableview class and textFieldShouldReturn function but nothing happens when I press "Done" button. Where can be a problem?

Thanks a lot!

Here's a code for Table View:

class MainTVC: UITableViewController, UITextFieldDelegate{ var tableParts: [Dictionary<String, Any>] = [] override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(true) tableParts = [ ["type": "title", "data": "Some data", "enabled": true], ["type": "date", "data": "Some data", "enabled": true], ["type": "location", "data": "Loading...", "enabled": true], ] tableView.reloadData() } override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tableParts.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell = tableParts[indexPath.row] switch(cell["type"] as! String) { ... case "textbox": let rTemplateTextBox = tableView.dequeueReusableCell(withIdentifier: "recapTextCell", for: indexPath) as! RTextCell rTemplateTextBox.textField.text = cell["data"] as? String ?? "No text" rTemplateTextBox.data = cell return rTemplateTextBox default: let cell = tableView.dequeueReusableCell(withIdentifier: "defCell", for: indexPath) cell.textLabel?.text = "Unknown type of cell!" return cell } } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() print("Should return!") return true } } 

And for a cell:

class RTextCell: UITableViewCell, UITextFieldDelegate { var textField = UITextField() var data: Dictionary<String, Any>? override func awakeFromNib() { super.awakeFromNib() textField.delegate = self let padding = UIView(frame: CGRect(x:0, y:0, width: 15, height: self.frame.height)) textField = UITextField(frame: CGRect(x:0, y:0, width: self.frame.width, height: 40)) textField.placeholder = "Your text here" textField.textColor = UIColor.white textField.tintColor = UIColor.white textField.backgroundColor = UIColor.clear textField.leftView = padding textField.leftViewMode = .always self.addSubview(textField) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() print("Should return") return true } func textFieldDidEndEditing(_ textField: UITextField) { if data != nil { data!["data"] = textField.text print("DATA: \(data!)") } else { print("No data") } } } 
7
  • Please include relevant code for both your UITableViewCell subclass and your tableview controller class. Commented Jul 31, 2017 at 8:33
  • @Cheslav i think my answer solve your problem Commented Jul 31, 2017 at 8:37
  • you are setting textfield.delegate in RTextCell class. So the textFieldShouldReturn will work only in that class. Where will you use data of textfield. pls explain? Commented Jul 31, 2017 at 9:54
  • @AadilAli I want to use field's text in my tableview class, there is a dictionary and I want to populate it with data from each textfield. There will be many textfields in each cell. Commented Jul 31, 2017 at 10:19
  • "Done" button is part of your cell? Commented Jul 31, 2017 at 11:35

2 Answers 2

2

First issue -- in your cell class, in awakeFromNib() you have:

// CREATE a UITextField var textField = UITextField() var data: Dictionary<String, Any>? override func awakeFromNib() { super.awakeFromNib() // assign self as the delegate of textField textField.delegate = self let padding = UIView(frame: CGRect(x:0, y:0, width: 15, height: self.frame.height)) // CREATE a NEW UITextField textField = UITextField(frame: CGRect(x:0, y:0, width: self.frame.width, height: 40)) 

So, when you create the NEW textField, it no longer has a delegate assigned to it. That's why nothing triggers textFieldShouldReturn or textFieldDidEndEditing.

Replace the UITextField(frame: ..) line with:

 textField.frame = CGRect(x:0, y:0, width: self.frame.width, height: 40) 

Next, instead of passing in a "data object" to then try and manipulate, think about using a call-back closure.

Change your cell class to this:

class RTextCell: UITableViewCell, UITextFieldDelegate { var textField = UITextField() // this will be our "call back" closure var didEndEditAction : ((String)->())? override func awakeFromNib() { super.awakeFromNib() textField.delegate = self let padding = UIView(frame: CGRect(x:0, y:0, width: 15, height: self.frame.height)) // just set the frame, don't create a NEW textField textField.frame = CGRect(x:0, y:0, width: self.frame.width, height: 40) textField.placeholder = "Your text here" textField.textColor = UIColor.white textField.tintColor = UIColor.white textField.backgroundColor = UIColor.clear textField.leftView = padding textField.leftViewMode = .always self.addSubview(textField) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() print("Should return") return true } func textFieldDidEndEditing(_ textField: UITextField) { // call back using a closure didEndEditAction?(textField.text ?? "") } } 

And then configure it like this:

 case "textbox": let rTemplateTextBox = tableView.dequeueReusableCell(withIdentifier: "recapTextCell", for: indexPath) as! RTextCell rTemplateTextBox.textField.text = cell["data"] as? String ?? "No text" // setup the "call back" closure rTemplateTextBox.didEndEditAction = { (newText) in let cell = self.myData[indexPath.row] cell["data"] = newText } return rTemplateTextBox 
Sign up to request clarification or add additional context in comments.

Comments

0

You can get cell textField data anywhere where your tableView is declared just use the following code

let indexPath = IndexPath(row: yourRow, section: yourSection) let cell:InputDataCell = yourTable.cellForRow(at: indexPath) as! InputDataCell if (cell.yourTextFieald.text?.characters.count)! { print(cell.yourTextFieald.text!) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.