简体   繁体   中英

Gather textfield text from a tableview cell (Swift)

I have a tableview with one textfield in each cell. I added a target like this:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customLevelCell") as! LevelTableViewCell

    cell.cellTextField.addTarget(self, action: #selector(ViewController.TextfieldEditAction), for: .editingDidEnd)

    return cell
}

But found out that I'm not able to use the indexpath.row / sender.tag to get the specific textfield text

@objc func TextfieldEditAction(sender: UIButton) {
}

So my question is how can I get the text after the user has edited one of the textfields.

Also how can i get the indexpath.row or sender.tag which will be used to collect the text they added to that specific textfield.

The easiest way to handle this is probably to use a delegate protocol…

In your cell

protocol LevelTableViewCellDelegate: class {
    func levelTableViewCell(_ levelTableViewCell: LevelTableViewCell, didEndEditingWithText: String?)
}

class LevelTableViewCell: UITableViewCell {
    @IBOutlet private weak var cellTextField: UITextField!
    var delegate: LevelTableViewCellDelegate?

    override func awakeFromNib() {
        cellTextField.addTarget(self, action: #selector(didEndEditing(_:)), for: .editingDidEnd)
    }

    @objc func didEndEditing(_ sender: UITextField) {
        delegate?.levelTableViewCell(self, didEndEditingWithText: sender.text)
    }
}    

In your view controller

class TableViewController: UITableViewController {

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "LevelTableViewCell") as! LevelTableViewCell
        cell.delegate = self
        return cell
    }
}

extension TableViewController: LevelTableViewCellDelegate {

    func levelTableViewCell(_ levelTableViewCell: LevelTableViewCell, didEndEditingWithText: String?) {

        let indexPath = tableView.indexPath(for: levelTableViewCell)

        // Now you have the cell, indexPath AND the string
    }

Also, note that the view outlet is be private . You'll find that you write cleaner code if you follow this rule

Following is the extension of UIView that can be used to get the cell or indexPath of the cell enclosing textField

extension UIView {

    var tableViewCell : UITableViewCell? {

        var subviewClass = self

        while !(subviewClass is UITableViewCell){

            guard let view = subviewClass.superview else { return nil }

            subviewClass = view
        }
        return subviewClass as? UITableViewCell
    }

    func tableViewIndexPath(_ tableView: UITableView) -> IndexPath? {

        if let cell = self.tableViewCell {

            return tableView.indexPath(for: cell)

        }
        return nil
    }
}

Example :-

    @objc func TextfieldEditAction(sender: UITextField) {

        //replace tableView with the name of your tableView
        guard let indexPath = sender.tableViewIndexPath(tableView) else {return}

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM