0

As the title said; I want to read the data from multiple UITextFields for each cell and store them in an array. How would I do so?

I have created a subclass CustomCell that has 2 UITextFields in it. P/S: the identifier for the cell is also CustomCell

Many thanks

class TableViewController : UITableViewController, UITextFieldDelegate {
var data = [input]()

@IBOutlet var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let customCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell

    customCell.input1.tag = indexPath.row
    customCell.input2.tag = indexPath.row
    customCell.input1.delegate = self
    customCell.input2.delegate = self

    return customCell
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return data.count
}

@IBAction func addButton(_ sender: Any) {
    table.beginUpdates()
    table.insertRows(at: [IndexPath(row: data.count-1, section: 0)], with: .automatic)
    table.endUpdates()
}

func textFieldDidEndEditing(_ textField: UITextField) {
    let indexPath = IndexPath(row: textField.tag, section: 0)

    if let customCell = self.table.cellForRow(at: indexPath) as? CustomCell{

        let a = customCell.Credit.text!.isEmpty ? no:String(customCell.input1.text!)
        let b = customCell.letterGrade.text!.isEmpty ? no:String(customCell.input2.text!))

        inputRead.append(input(string1: a, string2: b))

    }

 @IBAction func foo(_ sender: Any) {
    if inputRead.count == 0{
        return
    }
    //the rest of implementation

}

CustomCell class:

Import UIKit

public class CustomCell: UITableViewCell {

    @IBOutlet weak var input1: UITextField!
    @IBOutlet weak var input2: UITextField!

}
Alan Bui
  • 1
  • 3

2 Answers2

1

Update your code as follow in your view controller.

Assign textfield's delegate self to ViewController in cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  
    let customCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell

    customCell.input1.delegate = self
    customCell.input2.delegate = self

    return customCell
}

Now implemented text field delegate in your view controller.

func textFieldDidEndEditing(_ textField: UITextField) {
    guard let jobTaskCell = textField.superview?.superview as? CustomCell else {
        return
    }

    if textField == jobTaskCell.input1 {
        // Get text from textfield and store in array
    } else if textField == jobTaskCell.input2 {
        // Get text from textfield and store in array
    }
}

Note: Following code depends on how to place textfield in your cell. So make sure you need to check this recursively by adding and removing superView

guard let jobTaskCell = textField.superview?.superview as? CustomCell else {
    return
}

This simply mean that, just for when textfield inside tableview cell without any extra view:

textField.superview = contentView of TableViewCell

textField.superview?.superview = TableViewCell

I hope this will fix your issue.

Sagar Chauhan
  • 5,715
  • 2
  • 22
  • 56
  • There is a problem on line "customCell.textField1.delegate = self" as "Cannot assign value of type 'TableViewController' to type 'UITextFieldDelegate?". How should I fix it? – Alan Bui Jan 04 '19 at 07:38
  • 1
    @AlanBui fix it by adding `UITextFieldDelegate` to the `TableViewController` – iOSer Jan 04 '19 at 07:41
  • 1
    Update your code `class TableViewController : UITableViewController, UITextFieldDelegate { ... }` will fix your issue. – Mayur Karmur Jan 04 '19 at 07:54
  • Thanks everyone for helping!! – Alan Bui Jan 04 '19 at 10:12
  • Sorry but it does not seem to work. I append them to my array but it does not seem appending at all. What could possibly be the case? – Alan Bui Jan 04 '19 at 11:53
0

This can help you to store text in an array:-

1: Add indexPath.row as a tag to your textField in cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  

    let customCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell

    customCell.input1.tag = indexPath.row
    customCell.input2.tag = indexPath.row
    customCell.input1.delegate = self
    customCell.input2.delegate = self

    return customCell
}

2: In textField delegate method you can get your textField text

func textFieldDidEndEditing(_ textField: UITextField) {

    let indexPath = IndexPath(row: textField.tag, section: 0)

    if let customCell = self.table.cellForRow(at: indexPath) as? CustomCell {

        //From here you can get your particular input1 or input2 textfield text
         print(customCell.input1.text)
         print(customCell.input2.text)
    }
}
Abhishek Jadhav
  • 706
  • 5
  • 12
  • Sorry for this question. I am new to app development. Can I call the delegate method inside an action button? In addition, would this method reads all the data from all the cell? I imagine the method would involve a for loop or something like that. – Alan Bui Jan 04 '19 at 08:29
  • But it's not the proper way to call the delegate methods, and textFieldDidEndEditing textfield delegate method called when user stops typing and whole text will you get in textFieldt.text, Can you implement this answer? – Abhishek Jadhav Jan 04 '19 at 08:32
  • I see. Another question that currently I am placing 2 TextFields in a same row( [input1] [input2]). Would this affect the code in cellForRowAt method? – Alan Bui Jan 04 '19 at 08:41
  • oh wait nvm, sorry for a dumb question – Alan Bui Jan 04 '19 at 08:45
  • how would I store input1 and input2 to the array I have? Is the row same as the index to my array? I did some research and since each of the cell I have only 1 row, so that the index of array should be the same with the IndexPath.section right? – Alan Bui Jan 04 '19 at 09:35
  • Can you see my 2nd point in the answer you can get the text of both textField input1 and input2, you just want to create a string array and append it in if let where I wrote print statement – Abhishek Jadhav Jan 04 '19 at 09:38
  • Would it be insufficient because everytime the addButton method is called, I append an empty cell to my data array?. Do you have any suggestion for this? – Alan Bui Jan 04 '19 at 09:45
  • Why you are adding cell from clicking on a button, if you want to add a cell then add from cellForRowAt not from button action is not a proper way to add cell! – Abhishek Jadhav Jan 04 '19 at 09:54
  • I think everytime I call addButton, it is better to have a global variable count to determine the next row for the cell to be added. What do you think? – Alan Bui Jan 04 '19 at 09:57
  • Got it. Thank you – Alan Bui Jan 04 '19 at 09:59
  • If you like it, you can upward my answer or suggestions , Thanks @AlanBui – Abhishek Jadhav Jan 04 '19 at 10:00
  • I just did, I don't think it gets shown because my reputation is < 15 – Alan Bui Jan 04 '19 at 10:03
  • Sorry but it does not seem to work. I append them to my array but it does not seem appending at all. What could possibly be the case? – Alan Bui Jan 04 '19 at 11:54
  • Can you upload your code to question, then i can tell you? – Abhishek Jadhav Jan 04 '19 at 11:56
  • The foo button does not do anything resulted in inputRead.count is always 0 – Alan Bui Jan 04 '19 at 12:07
  • You want whenever user is going to type in input1 or input2 textfield it append on array, is this you want? – Abhishek Jadhav Jan 04 '19 at 12:10
  • Yeah, same thing for other cell as well – Alan Bui Jan 04 '19 at 12:15
  • Why you're created inputRead.append(input(string1: a, string2: b)) input model array and appending at a time user is going to type one textfield so one textfield text is going to append so you have to create string array for that then append just you have to check input1.resignFirstResponder then append it in the string array @AlanBui – Abhishek Jadhav Jan 04 '19 at 12:24
  • inputRead is an array of input object. The reason that foo's implementation involves 2 variables in parallel. – Alan Bui Jan 04 '19 at 12:28