Kevin
Kevin

Reputation: 1189

Conforming to a UITextField Delegate Using a CustomCell (subclass) textfield

I have a subclass, CustomCell, which inherits from my parent class, CreateEvent. The subclass describes the individual cells for the table view cell, which is on the CreateEvent View controller. In one specific cell, I have a textfield, that is linked to the CustomCell file, but I am having trouble getting the value from that textfield when a user enters into the textfield. I am also having trouble dismissing the keyboard with outside touches and pressing the return key, but I am primarily focused on getting the text from the textfield. I am familiar with doing these functionalities on ONE normal swift file but because this is a subclass and two swift files, I'm not sure what to do. This is my code:

class CustomCell: UITableViewCell, UITextFieldDelegate {

@IBOutlet weak var entranceFeeTextField: UITextField!

override func awakeFromNib() {
   super.awakeFromNib()

}

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

and

class CreateEventVC: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomCellDelegate, UITextFieldDelegate {

override func viewDidLoad() {
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
   let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String, for: indexPath) as! CustomCell

// the following code describes the array for an expandable drop down 
if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
    if let primaryTitle = currentCellDescriptor["primaryTitle"] {
        cell.textLabel?.text = primaryTitle as? String
    }

    eventType = ((cellDescriptors[0] as! NSMutableArray)[0] as! NSDictionary)["primaryTitle"]! as! String
    if let secondaryTitle = currentCellDescriptor["secondaryTitle"] {
        cell.detailTextLabel?.text = secondaryTitle as? String
    }
}
else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextfield" {
    cell.textField.placeholder = currentCellDescriptor["primaryTitle"] as? String
}


else if currentCellDescriptor["cellIdentifier"] as! String == "idCellValuePicker" {
    cell.textLabel?.text = currentCellDescriptor["primaryTitle"] as? String
}

cell.delegate = self

return cell
}


func textFieldShouldEndEditing(textField:UITextField) -> Bool {
entranceFeeAmount = cell.entranceFeeTextField.text!

return true;
}

}

My main question is that I am not sure how to set the textfield delegate, and how to properly conform to the delegate.

Upvotes: 2

Views: 1107

Answers (2)

teeying
teeying

Reputation: 33

Since only one specific cell contains a text field, in your custom cell's awakeFromNib(), check if the text field exists then set the delegate of the text field.

override func awakeFromNib() {
    super.awakeFromNib()

    if (self.entranceFeeTextField != nil) {
        self.entranceFeeTextField.delegate = self as UITextFieldDelegate
    }
}

You can pass the text from the text field to CreateEvent View controller using delegation.

To implement delegation, create a protocol at the top of your CustomCell class and add a method to transfer the string from CustomCell to CreateEventVC.

protocol CustomCellDelegate {
    func getTextFieldString(string: String)
}

Declare a delegate variable in your CustomCell class.

var delegate: CustomCellDelegate?

Trigger the protocol method in textFieldDidEndEditing:

func textFieldDidEndEditing(_ textField: UITextField) {
    delegate?.getTextFieldString(string: self.entranceFeeTextField.text!)
}

Now, let CreateEventVC conform to the CustomCellDelegate protocol and implement func getTextFieldString(string: String) inside CreateEventVC.

func getTextFieldString(string: String) {
    print(string) //do whatever you want with it 
}

In tableView(_, cellForRowAt:), remember to set cell.delegate = self because we want CreateEventVC to be the receiver.

Upvotes: 3

Léo Natan
Léo Natan

Reputation: 57050

Unclear what you want to achieve. You have set your delegate to be the cell, but want to update a property of the controller (entranceFeeAmount).

There are two ways of going at it. If you intend to have only one such cell, you can set the delegate to be your controller, rather than the cell itself. You can do that in tableView(_, cellForRowAt:). That way, the controller will hear the text field's events, and handle them.

If you will have more than such cell, you will set the delegate in the cell's awakeFromNib(). That gets called when the cell is instantiated from the storyboard / NIB. The cell will be the delegate, rather than the controller, so you need to move that delegate method to the cell itself. However, now that each cell hears about its own text field, you need to notify the controller for each cell. This is a complex topic, and can be achieved using delegation, where the controller is a delegate of the cells.

Upvotes: 0

Related Questions