1

I have a UITableView and my prototype cell consists of a label and a TextField. I also have a class MyClass that contains functions func1, func2, fun3, ... I have several ViewControllers that use the same tableViewCell prototype. Each viewController will have an instance of MyClass, called inst1, inst2, and inst3. When I enter text into FirstViewController's TableView I want each row to call a function from the instance of MyClass that corresponds to the row.

So when I enter text into row 1 on the FirstViewController I want to pass the data entered into the textField into func1 of inst1. When data is entered into row 2 of FirstViewController I want the data in the textfield to be passed into func2 of inst1. And so on and so forth down the rows.

I am very new to this and would really appreciate some help figuring out how to do this. Let me know if that doesn't make sense and I can try to rephrase it. I really need help with this. Thanks in advance!

*Updated question to show my code

Below is my Code: FirstViewController.swift

extension FirstViewController: MyCellDelegate {
    func MyCell(_ cell: UITableViewCell, didEnterText text: String) {
        if let indexPath = tableView.indexPath(for: cell) {
            if (indexPath.hashValue == 0) {
                inst1.func1(one: text)
            }
            if (indexPath.hashValue == 1) {
                inst1.func2(two: text)
            }
        }
        totalText.text = inst1.getMyTotal()
    }
}

import UIKit

class FirstViewController: UIViewController,  UITableViewDataSource, UITableViewDelegate {
    let inst1 = MyClass()
    @IBOutlet weak var totalText: UILabel!
    @IBOutlet weak var tableView: UITableView!

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 11
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell") as! TableViewCell
        let text = cell.cellData[indexPath.row]
        cell.myTextField.tag = indexPath.row
        cell.delegate = self
        cell.myLabel.text = text
        cell.myTextField.placeholder = text
        return cell
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
    }

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

TableViewCell.swift

import UIKit
protocol MyCellDelegate: class {
    func MyCell(_ cell: UITableViewCell, didEnterText text: String)
}

class TableViewCell: UITableViewCell {
    weak var delegate: MyCellDelegate?

    public var cellData: [String] = ["1","2","3","4","5","6","7","8","9","10","11"]

    @IBOutlet weak var myLabel: UILabel!

    @IBOutlet weak var myTextField: UITextField!

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

    override func setSelected(_ selected: Bool, animated: Bool) {
    }
}

When I set a breakpoint in the FirstViewController extension it never runs that code.

win22jim
  • 23
  • 3

1 Answers1

1

In WillDisplayCell add the tag to the UITextField. Also create a protocol to notify the Corrosponding viewController and set itself as the delegate here.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
 let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier")
 cell.textField.tag = indexPath.row
 cell.delegate = self
 }

The protocol in your cell class will look something like this

protocol MyCellDelegate: class {
func MyCell(_ cell: UITableViewCell, didEnterText text: String)
}

class MyCell: UITableViewCell, UITextFieldDelegate {
weak var delegate: MyCellDelegate?
override fun awakeFromNib() {
 super.awakeFromNib()
 textField.delegate = self
 }
//All the remaining code goes here


func textFieldShouldReturn(_ textField: UITextField) -> Bool {   //delegate method
textField.resignFirstResponder()
delegate?.MyCell(self, didEnterText: textField.text! )
return true
}
}

Now again in your FirstViewController which has conformed to be its delegate do this

extension FirstViewController: MyCellDelegate {
 func MyCell(_ cell: UITableViewCell, didEnterText text: String) {
 if let indexPath = tableView.indexPathForCell(cell) {
   // call whichever method you want to call based on index path
  }
 }
Keshav Raj
  • 376
  • 1
  • 7
  • How do you differentiate the rows for the correct function calls? i.e. inside the extension it won't let me use code like this if (indexPath == 0) { inst1.func1(textField.text) } how do I tell the different rows to call different functions? Also inst1 would be outside of scope inside the extension. – win22jim Jun 29 '18 at 21:34
  • I updated the question to show my code. I integrated the code that you mentioned above, but func1 and func2 are never run when I enter text. Any idea what I might be missing? – win22jim Jun 29 '18 at 22:42
  • I changed it to indexpath.row but when I set a breakpoint in that extension it never hits the breakpoint. Somehow that code is never called. – win22jim Jun 30 '18 at 04:20
  • Have you set the textField Delegate in your UITableViewCell. textField.delegate = cell.... Check where func textFieldShouldReturn(_ textField: UITextField) -> Bool this method is getting called or not. Also in your code I can't see anywhere you are written this method and setting cell as uitextfieljddelegate. – Keshav Raj Jun 30 '18 at 04:40
  • I set a breakpoint in textFieldShouldReturn and it was never called. As far as setting the uitextfielddelegate and textfield.delegate = cell, I'm not sure where in my code all that needs to be. My code is exactly as shown above, – win22jim Jun 30 '18 at 05:44
  • I added the text field delegate in the cell and still none of the code with my previous breakpoints are being called. – win22jim Jun 30 '18 at 16:30
  • Put your code in the GitHub and share the link here – Keshav Raj Jun 30 '18 at 16:49
  • The repository is private. Could you send me your username and I can add you as a collaborator? – win22jim Jun 30 '18 at 17:22
  • I added you to the GitHub repository. Let my know if you have any questions and if you find the problem. Thanks! – win22jim Jul 01 '18 at 17:46
  • So you don't have return button. So when do you want to return? Or it will be simply on some change in textfield? – Keshav Raj Jul 02 '18 at 02:23
  • Well the way it is designed is so that in the settings screen you can change between the numberPad and the standard keyboard (still to be implemented) but the numberPad doesn’t have a return button. So I was originally using editingDidEnd or some other action call that works on any change in the textfield. – win22jim Jul 02 '18 at 02:26
  • I changed the method and it still doesn’t work for the numberPad, but if I switch it back to the default keyboard and press enter then it works. Any idea how to get it to work with numberPad and when you tap the background to dismiss and not just on the return key? – win22jim Jul 02 '18 at 03:37
  • Check the pull request – Keshav Raj Jul 02 '18 at 03:40
  • Better have conversation at some other place rather than here – Keshav Raj Jul 02 '18 at 03:41