Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: retrieving text from a UITextField in a custom UITableViewCell and putting it in an array

I'm making a very simple app where the user enters the number of people in the first Screen.

In the second screen it generates a number of UITableViewCell based on the number the user entered in the first screen. The UITableViewCell have a UITextField in them and I'm trying to store the data entered in those fields in an array once the user clicks to go to the third screen.

How can I do that?
Thanks in advance!

Edit: I'm using the storyboard.

Here is what the code that calls for the custom UITableViewCell looks like for my UIViewController:

func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
        
    var cell: EditingCell = tableView.dequeueReusableCellWithIdentifier("Cell") as EditingCell
    
    if indexPath.row % 2 == 0{
        cell.backgroundColor = UIColor.purpleColor()
    } else {
        cell.backgroundColor = UIColor.orangeColor()
    }
    
    let person = arrayOfPeople[indexPath.row]
    
    cell.setCell(person.name)
    
            
    return cell
}

Here is what the code for the UITableViewCell looks like:

class EditingCell: UITableViewCell{
    
    @IBOutlet weak var nameInput: UITextField!
    
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
    
    
    func setCell(name:String){
        self.nameInput.placeholder = name
    }
}
like image 322
Unis Barakat Avatar asked Dec 31 '14 22:12

Unis Barakat


1 Answers

There is a problem with your approach if the number of rows in your table exceeds the number that can fit on screen. In that case, the cells that scroll off-screen will be re-used, and the contents of the nameInput textField will be lost. If you can be sure that this will never happen, use the following code (in the method that handles button taps) to compose your array:

        var arrayOfNames : [String] = [String]()
        for var i = 0; i<self.arrayOfPeople.count; i++ {
            let indexPath = NSIndexPath(forRow:i, inSection:0)
            let cell : EditingCell? = self.tableView.cellForRowAtIndexPath(indexPath) as EditingCell?
            if let item = cell?.nameInput.text {
                arrayOfNames.append(item)
            }
        }
        println("\(arrayOfNames)")

Alternatively....

However, if it is possible that cells will scroll off-screen, I suggest a different solution. Set the delegate for the nameInput text fields, and then use the delegate methods to grab the names as they are entered.

First, add variables to your view controller, to hold the array and the row number of the text field currently being edited.

    var arrayOfNames : [String] = [String]()
    var rowBeingEdited : Int? = nil

Then, in your cellForRowAtIndexPath method, add:

    cell.nameInput.text = "" // just in case cells are re-used, this clears the old value
    cell.nameInput.tag = indexPath.row
    cell.nameInput.delegate = self

Then add two new functions, to catch when the text fields begin/end editing:

func textFieldDidEndEditing(textField: UITextField) {
    let row = textField.tag
    if row >= arrayOfNames.count {
        for var addRow = arrayOfNames.count; addRow <= row; addRow++ {
            arrayOfNames.append("") // this adds blank rows in case the user skips rows
        }
    }
    arrayOfNames[row] = textField.text
    rowBeingEdited = nil
}

func textFieldDidBeginEditing(textField: UITextField) {
    rowBeingEdited = textField.tag
}

When the user taps the button, they might still be editing one of the names. To cater for this, add the following to the method that handles the button taps:

        if let row = rowBeingEdited {
            let indexPath = NSIndexPath(forRow:row, inSection:0)
            let cell : EditingTableViewCell? = self.tableView.cellForRowAtIndexPath(indexPath) as EditingTableViewCell?
            cell?.nameTextField.resignFirstResponder()
        }

This forces the textField to complete editing, and hence trigger the didEndEditing method, thereby saving the text to the array.

like image 86
pbasdf Avatar answered Oct 02 '22 16:10

pbasdf