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];
}
break;
}
...
}
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)
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!
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
tableView.cellForRowAtIndexPath(indexPath).textField.becomeFirstResponder()
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 {
textField.resignFirstResponder()
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:
https://mega.nz/#!B1ASDIQT!8-diyv_Fd2H66nb08gs3ObzlQqVHKUUIs4U_BbI6s4s
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
Step 2- Now Assign Created Class to TableView cell in Storyboard as Below
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
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()
{
super.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
DispatchQueue.main.async
{
///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()
{
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
----> My StoryBoard
---> Simulator Output
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() {
super.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() {
super.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
self.addSubview(textField)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
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
How to Export Uiimage Array as a Movie
How to Take a Screenshot Programmatically on Ios
Set the Maximum Character Length of a Uitextfield
Hide Strange Unwanted Xcode Logs
How to Return Value from Alamofire
Adjust Uilabel Height Depending on the Text
Can You Animate a Height Change on a Uitableviewcell When Selected
Check For Internet Connection With Swift
Nsnotificationcenter Addobserver in Swift
Converting String to Int With Swift
Undefined Symbols For Architecture Arm64
Ios 7 Status Bar Back to iOS 6 Default Style in Iphone App
Exc_Bad_Access Signal Received
Ios Uiimagepickercontroller Result Image Orientation After Upload
Getting the Difference Between Two Dates (Months/Days/Hours/Minutes/Seconds) in Swift