Having a Uitextfield in a Uitableviewcell

Accessing UITextField in a custom UITableViewCell

I think what the OP is trying to understand is how to access the UITextField value once the user has entered data into each fields. This will not be available at the time the cells are created as suggested by @willcodejavaforfood.

I've been implementing a form and trying to make it as user friendly as possible. It is doable but be aware that it can get quite convoluted depending on the number of UITableViewCells / UITextFields you have.

Firstly to your question re: accessing the values of UITextField:

1) Make your view controller a <UITextFieldDelegate>

2) Implement the following method:

- (void) textFieldDidEndEditing:(UITextField *)textField {
NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell*)[[textField superview] superview]]; // this should return you your current indexPath

// From here on you can (switch) your indexPath.section or indexPath.row
// as appropriate to get the textValue and assign it to a variable, for instance:
if (indexPath.section == kMandatorySection) {
if (indexPath.row == kEmailField) self.emailFieldValue = textField.text;
if (indexPath.row == kPasswordField) self.passwordFieldValue = textField.text;
if (indexPath.row == kPasswordConfirmField) self.passwordConfirmFieldValue = textField.text;
else if (indexPath.section == kOptionalSection) {
if (indexPath.row == kFirstNameField) self.firstNameFieldValue = textField.text;
if (indexPath.row == kLastNameField) self.lastNameFieldValue = textField.text;
if (indexPath.row == kPostcodeField) self.postcodeFieldValue = textField.text;

I also use a similar syntax to make sure the current edited field is visible:

- (void) textFieldDidBeginEditing:(UITextField *)textField {
CustomCell *cell = (CustomCell*) [[textField superview] superview];
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];

And finally, you can handle textViewShouldReturn: in a similar way:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell*)[[textField superview] superview]];
switch (indexPath.section) {
case kMandatorySection:
// I am testing to see if this is NOT the last field of my first section
// If not, find the next UITextField and make it firstResponder if the user
// presses ENTER on the keyboard
if (indexPath.row < kPasswordConfirmField) {
NSIndexPath *sibling = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
CustomCell *cell = (CustomCell*)[self.tableView cellForRowAtIndexPath:sibling];
[cell.cellTextField becomeFirstResponder];
} else {
// In case this is my last section row, when the user presses ENTER,
// I move the focus to the first row in next section
NSIndexPath *sibling = [NSIndexPath indexPathForRow:kFirstNameField inSection:kOptionalSection];
MemberLoginCell *cell = (MemberLoginCell*)[self.memberTableView cellForRowAtIndexPath:sibling];
[cell.cellTextField becomeFirstResponder];

obtain data from UITextField in UITableViewCell

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)

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

private func commonInit() {
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!

getting value from uitextfield in uitableview

I have resolved my problem like follows.

I have created a unique ID for my Datasource and i use that to determine with cell has been updated.

var row = 0
var section = 0

for var k = 0; k < fieldsWSections.count; k++ {
for var kk = 0; kk < fieldsWSections[k].count; kk++ {
if fieldsWSections[k][kk].ID == String(textField.tag) {
section = k
row = kk

if data[fieldsWSections[section][row].name] != textField.text {
newData[fieldsWSections[section][row].ID] = textField.text

So i don't need to know the indexPath anymore.

How to properly add UITextField to UITableViewCell

Create a custom UITableView cell as a xib and make a corresponding .swift file for this. Add a textField to the cell and create an IBOutlet for the textField in the custom .swift class. Make sure your constraints are set in this xib.

In your ViewController .swift class, make the func tableView(cellForRowAtIndexPath) return your custom cell.

You do not have to set the firstResponder because the keyboard will come up by default. Unless of your cell is basically just a textField, it doesn't seem wise to have the didSelectRowAtIndexPath to always bring up the keyboard. If, for some reason that the cell always takes the touch action, then use didSelectRowAtIndexPath, but use


Set textField delegate to the custom cell and add this in the CustomTableViewCell.swift to dismiss the keyboard upon press of return key:

func textFieldShouldReturn(textField: UITextField) -> Bool {
return false

Side note: The keyboard will not show in the simulator unless you deselected the option to use the hardware keyboard.

Here is a sample project with what I think you are trying to achieve:

How to connect UITextField to UITableView?

You can Not directly Connect outlet of Any Thing Embedded In TableCell

Follow Steps To Perform Code operation with Outlets Connected

Step 1- Create a new tableViewCell Class as Below ScreenSHot

Sample Image

Step 2- Now Assign Created Class to TableView cell in Storyboard as Below

Sample Image

Step 3- Time to connect outlets in Cell class created by normally dragging the TF to be Connected in cell class

output will be as Below

Sample Image

Step 4- Required Coding

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomTableCell

cell.fileNameLabel.text = coreClassObject.audioFileName
cell.durationLabel.text = coreClassObject.audioDuration
cell.uploadedStatusLabel.text = coreClassObject.audioUploadStatus

cell.playButton.addTarget(self, action: #selector(playSoundAtSelectedIndex(sender:)), for: .touchUpInside)
return cell

Re-Update Answer to Access TF in ViewDidLoad

----> my ViewController class

import UIKit

class tableViewVC: UIViewController

let staticArrayy = ["1","1","1","1","1","1","1","1","1","1"]

@IBOutlet weak var myDemoTableView: UITableView!

override func viewDidLoad()

// Do any additional setup after loading the view.

///Set Delegates
myDemoTableView.delegate = self
myDemoTableView.dataSource = self

///Async operation
///To make sure cells are loaded
///Create a Reference TF
let MyTf : UITextField!

///Get Index Path of Which TF is to be Accessed
let indexPath = IndexPath(row: 0, section: 0)

///Create A new cell Reference
let newCell = self.myDemoTableView.cellForRow(at: indexPath)! as! CustomTableViewCell

///Assign Cell TF to our created TF
MyTf = newCell.cellTF

///Perform Changes
MyTf.text = "Changes text"


extension tableViewVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return staticArrayy.count

//Setting cells data
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = self.myDemoTableView.dequeueReusableCell(withIdentifier: "Cell") as! CustomTableViewCell
cell.cellTF.placeholder = staticArrayy[indexPath.row]
return cell

//Setting height of cells
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 60

---> My cell class

import UIKit

class CustomTableViewCell: UITableViewCell

@IBOutlet weak var cellTF: UITextField!

override func awakeFromNib()
// Initialization code

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

// Configure the view for the selected state


----> My StoryBoard

Sample Image

---> Simulator Output

Sample Image

Get uitextfield data from custom uitableview cell - Swift

First issue -- in your cell class, in awakeFromNib() you have:

// CREATE a UITextField
var textField = UITextField()
var data: Dictionary<String, Any>?

override func awakeFromNib() {

// assign self as the delegate of textField
textField.delegate = self

let padding = UIView(frame: CGRect(x:0, y:0, width: 15, height: self.frame.height))

// CREATE a NEW UITextField
textField = UITextField(frame: CGRect(x:0, y:0, width: self.frame.width, height: 40))

So, when you create the NEW textField, it no longer has a delegate assigned to it. That's why nothing triggers textFieldShouldReturn or textFieldDidEndEditing.

Replace the UITextField(frame: ..) line with:

    textField.frame = CGRect(x:0, y:0, width: self.frame.width, height: 40)

Next, instead of passing in a "data object" to then try and manipulate, think about using a call-back closure.

Change your cell class to this:

class RTextCell: UITableViewCell, UITextFieldDelegate {

var textField = UITextField()

// this will be our "call back" closure
var didEndEditAction : ((String)->())?

override func awakeFromNib() {

textField.delegate = self

let padding = UIView(frame: CGRect(x:0, y:0, width: 15, height: self.frame.height))

// just set the frame, don't create a NEW textField
textField.frame = CGRect(x:0, y:0, width: self.frame.width, height: 40)
textField.placeholder = "Your text here"
textField.textColor = UIColor.white
textField.tintColor = UIColor.white
textField.backgroundColor = UIColor.clear
textField.leftView = padding
textField.leftViewMode = .always



func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("Should return")
return true

func textFieldDidEndEditing(_ textField: UITextField) {
// call back using a closure
didEndEditAction?(textField.text ?? "")


And then configure it like this:

    case "textbox":
let rTemplateTextBox = tableView.dequeueReusableCell(withIdentifier: "recapTextCell", for: indexPath) as! RTextCell
rTemplateTextBox.textField.text = cell["data"] as? String ?? "No text"

// setup the "call back" closure
rTemplateTextBox.didEndEditAction = {
(newText) in
let cell = self.myData[indexPath.row]
cell["data"] = newText

return rTemplateTextBox

Related Topics

Leave a reply