Dustin Spengler
Dustin Spengler

Reputation: 7761

obtain data from UITextField in UITableViewCell

I have crated this tableview to obtain the users children's names and store them into an array called dependentsArray:

enter image description here

I have searched through stackoverflow, Apple documentation, google, and youtube tutorials, and cant seem to find a solution. This seems like it should be simple but its causing quite the headache. The closest i found to a solution was this post:

getting data from each UITableView Cells Swift

However, i am not obtaining the cells textfield value by tapping them, so i cannot use didDeselectRowAtIndexPath. I wish to obtain the text values when i tap the "Next" button.

The tableview expands and contracts its cell count based on an integer called dependentsCount. I increment and decrement the dependentsCount like so:

    @IBAction func subtractDependentButtonClick(sender: AnyObject) {
    dependentsCount -= 1
    dependentsTableView.reloadData()
    fadeTransition(0.3)
}

@IBAction func addDependentButtonClick(sender: AnyObject) {
    dependentsCount += 1
    dependentsTableView.reloadData()
    fadeTransition(0.3)
}

The ways in which ive tried to obtain the value of text fields are as follows:

    @IBAction func nextButtonPress(sender: AnyObject) {
    var index = 0
    var cell = self.dependentsTableView.cellForRowAtIndexPath(NSIndexPath(index: index)) as! DependentsTableViewCell

    while index < dependentsCount
    {
        self.dependentsArray.append(cell.nameTextField.text!)
        index += 1
    }
    self.performSegueWithIdentifier("showNextVC", sender: nil)

}

which crashed the app ^^

    func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = dependentsTableView.dequeueReusableCellWithIdentifier("Cell") as! DependentsTableViewCell
    dependentsArray.append(cell.nameTextField.text!)
    print("\(dependentsArray)")
}

which does nothing ^^

what is the correct way to obtain tableview cell's textfield text?

Upvotes: 1

Views: 1190

Answers (2)

werediver
werediver

Reputation: 4757

I would suggest you to try something like I wrote in this gist for you (the source is for interactive playground).

Briefly, I suggest introducing a model for your data:

class Model {

    let placeholder: String?
    var text: String?

    init(placeholder: String?, text: String? = nil) {
        self.placeholder = placeholder
        self.text = text
    }

}

Then making a list of models to actually store the data:

// Sample items.
let items = [
    TextFieldCell.Model(placeholder: "1"),
    TextFieldCell.Model(placeholder: "2"),
    TextFieldCell.Model(placeholder: "3", text: "xxx"),
    TextFieldCell.Model(placeholder: "4"),
    TextFieldCell.Model(placeholder: "5"),
    TextFieldCell.Model(placeholder: "6")
]

And connecting visible cells to the corresponding models via an appropriate data source.

The cell may be like this:

class TextFieldCell: UITableViewCell, SmartCell, UITextFieldDelegate {

    var model: Model? {
        didSet {
            textField.placeholder = model?.placeholder
            textField.text = model?.text
        }
    }

    let textField = UITextField()

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }

    private func commonInit() {
        contentView.addSubview(textField)
        textField.delegate = self
    }

    override func layoutSubviews() {
        textField.frame = contentView.bounds.insetBy(dx: 15, dy: 8)
    }

    func loadModel(m: Model) {
        model = m
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let text = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)
        // Update the model.
        model?.text = text
        return true
    }
}

After that, you can read the data entered by user at any time from the list of the models.

Play with the gist in an interactive iOS playground!

Upvotes: 3

Mazel Tov
Mazel Tov

Reputation: 2192

updated answer, new didDeselectRowAtIndexPath

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
if let textView = self.view.viewWithTag(indexPath.row) as? UITextField
{
    dependentsArray.append(textView.text!)
}
print("\(dependentsArray)")
}

and put this inside cellForRowAtIndexPath

cell.nameTextField.tag = indexPath.row

Upvotes: 0

Related Questions