Detecting textfieldshouldreturn from Custom TableViewCell in TableViewController to Add New Row - ios

I want to add a new row in my TableView when the user presses the return key inside the Custom TableViewCell, which includes a TextField. However, I cannot find a way to do so... how do I view the events of the TextField in my TableView so I can add the row?
My TableViewController
class TableViewController: UITableViewController, CustomCellDelegate,
UITextFieldDelegate {
var rowCount = 1
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
// MARK: - Table view data source
...
// Doesn't Do Anything
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let indexPath = IndexPath(row: rowCount-1, section: 1)
tableView.insertRows(at: [indexPath], with: .automatic)
view.endEditing(true)
return true
}
// Also does nothing
func didReturn(cell: AddActivityTableViewCell, string: String?) {
let indexPath = IndexPath(row: rowCount-1, section: 1)
tableView.insertRows(at: [indexPath], with: .automatic)
view.endEditing(true)
rowCount += 1
}
My CustomTableViewCell
protocol CustomCellDelegate: class {
func didReturn(cell: CustomTableViewCell, string: String?)
}
class CustomTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
weak var delegate: CustomCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
textField.delegate = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
public func configureTextField(text: String?, placeholder: String) {
textField.text = text
textField.placeholder = placeholder
textField.accessibilityValue = text
textField.accessibilityLabel = placeholder
}
public func editableTextField(editable: Bool) {
if editable == true {
textField.isEnabled = true
} else {
textField.isEnabled = false
}
}
// This works
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
delegate?.didReturn(cell: self, string: textField.text)
return true
}
}
Thanks!

I think you missed the set delegate in the cell . Please find the code below which works fine for me
ViewController
class TableViewController: UITableViewController, CustomCellDelegate, UITextFieldDelegate {
var rowCount = 1
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowCount
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : CustomTableViewCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
cell.textField.placeholder = "Row \(indexPath.row)"
cell.delegate = self
return cell
}
func didReturn(cell: CustomTableViewCell, string: String?) {
rowCount += 1
let indexPath = IndexPath(row: rowCount-1, section:0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
view.endEditing(true)
}
}
Custom Cell
protocol CustomCellDelegate: class {
func didReturn(cell: CustomTableViewCell, string: String?)
}
class CustomTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
weak var delegate: CustomCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
textField.delegate = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
public func configureTextField(text: String?, placeholder: String) {
textField.text = text
textField.placeholder = placeholder
textField.accessibilityValue = text
textField.accessibilityLabel = placeholder
}
public func editableTextField(editable: Bool) {
if editable == true {
textField.isEnabled = true
} else {
textField.isEnabled = false
}
}
// This works
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
delegate?.didReturn(cell: self, string: textField.text)
return true
}
}

Related

How to make textField in TableViewCell editable when edit button of NavigationBar is pressed?

Developing an iOS application with Xcode ver 9.2, Swift.
When the edit button on the top right of the NavigationBar is pressed, how to change the textField in the TableViewCell to make it editable?
To prevent the TextField from being edited in the initial display, I set textField.isEnabled = false with awakeFromNib() in the TableViewCell.swift.
When the edit button is pressed, I want to set it to true so that I can edit the TextField.
Could you tell me how?
Relationship between object placement and code (in parentheses) is below.
NavigationController - TableViewController (TableViewController.swift) - TableViewCell (TableViewCell.swift) - TextField
Here is the code.
TableViewController.swift
import UIKit
class TableViewController: UITableViewController, TableViewCellDelegate {
#IBOutlet var ttableView: UITableView!
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inputCell", for: indexPath) as! TableViewCell
cell.textField.text = array[indexPath.row]
cell.delegate = self
return cell
}
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> () {
let path = tableView.indexPathForRow(at: cell.convert(cell.bounds.origin, to: tableView))
array[(path?.row)!] = value
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let cell = tableView.cellForRow(at: sourceIndexPath) as! TableViewCell
let moveData = cell.textField.text
array.remove(at: sourceIndexPath.row)
array.insert(moveData!, at: destinationIndexPath.row)
}
}
TableViewCell.swift
import UIKit
protocol TableViewCellDelegate {
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> ()
}
class TableViewCell: UITableViewCell, UITextFieldDelegate {
var delegate: TableViewCellDelegate! = nil
#IBOutlet weak var textField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
textField.returnKeyType = .done
// To prevent the TextField from being edited in the initial display
textField.isEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate.textFieldDidEndEditing(cell: self, value: textField.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
I added the following from the first time question and answers.
Editing screen shot: after edit button is pressed
If there are many elements of the array, the cells will be outside the screen, but I want to make all textField editable as well.
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt"]
Editing screen shot for many elements
Finally resolved code
TableViewController.swift
import UIKit
class TableViewController: UITableViewController, TableViewCellDelegate {
#IBOutlet var ttableView: UITableView!
// var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee"]
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(rightBarButtonItemTapped))
}
// handle tap by button...
#objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
ttableView.setEditing(!ttableView.isEditing, animated: true)
navigationItem.rightBarButtonItem?.title = ttableView.isEditing ? "Done" : "Edit"
navigationItem.rightBarButtonItem?.style = ttableView.isEditing ? .done : .plain
ttableView.visibleCells.forEach { cell in
guard let cell = cell as? TableViewCell else { return }
cell.textField.isEnabled = ttableView.isEditing
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inputCell", for: indexPath) as! TableViewCell
cell.textField.text = array[indexPath.row]
cell.textField.isEnabled = tableView.isEditing
cell.delegate = self
return cell
}
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> () {
let path = tableView.indexPathForRow(at: cell.convert(cell.bounds.origin, to: tableView))
array[(path?.row)!] = value
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
if tableView.isEditing {
return UITableViewCellEditingStyle.delete
} else {
return UITableViewCellEditingStyle.none
}
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let cell = tableView.cellForRow(at: sourceIndexPath) as! TableViewCell
let moveData = cell.textField.text
array.remove(at: sourceIndexPath.row)
array.insert(moveData!, at: destinationIndexPath.row)
}
}
TableViewCell.swift
import UIKit
protocol TableViewCellDelegate {
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> ()
}
class TableViewCell: UITableViewCell, UITextFieldDelegate {
var delegate: TableViewCellDelegate! = nil
#IBOutlet weak var textField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
textField.returnKeyType = .done
//textField.isEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate.textFieldDidEndEditing(cell: self, value: textField.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
First, you should handle navigation button tap, find cell(s) with textField and then set textField.isEnabled = true.
You can do something like this:
override func viewDidLoad() {
super.viewDidLoad()
// in your code `self.editButtonItem` is the `UIBarButtonItem`, so make sure that it configured properly
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(rightBarButtonItemTapped))
}
// handle tap by button...
#objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
// and set `textField.isEnabled` to all `visibleCells`
ttableView.visibleCells.forEach { cell in
guard let cell = cell as? TableViewCell { else return }
cell.textField.isEnabled = true
}
// or set `isEnabled` to specific `textField` at index 0
if let cell = ttableView.cellForRow(at: IndexPath(row: 0, section: 0)) {
cell.textField.isEnabled = true
}
}
UPD.
Base on your screenshot you:
doesn't need to set textField.isEnabled = false
you just need setEditing for tableView and show appropriate title for button in navigation bar.
Example:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(rightBarButtonItemTapped))
}
#objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
ttableView.setEditing(!ttableView.isEditing, animated: true)
navigationItem.rightBarButtonItem?.title = ttableView.isEditing ? "Done" : "Edit"
navigationItem.rightBarButtonItem?.style = ttableView.isEditing ? .done : .plain
}
LAST UPD
Ok, now only steps you should do:
remove from awakeFromNib code that disable textField
in cellForRowAtIndexPath method in your viewController write cell.textField.isEnabled = tableView.isEditing
to set tableView in editing mode use my UPD code
to enable all textFields in cells you should use approach from original answer with visibleCells (i updated this part, now you shouldn't have any error). note, that this code apply only for currently visible cells. for others it also works, but set textField enabled part goes in cellForRowAtIndexPath method because these cells will appear on the screen.
you can do so by creating an action of your navigation barbutton item , and in that action you can simply do the textField enabled, as shown below:
#IBAction func editTapped(_ sender: Any) {
print("editTapped")
for i in 0..< ttableView.visibleCells.count{
let cell = ttableView.cellForRow(at: IndexPath(row: i, section: 0)) as! TableViewCell
cell.textField.isEnabled = true
}
}

How do you save user answers received from a textField on a tableView using Swift

I have made a little quiz where a tableView holds different questions and answers as labels and textFields.
If the correct answer is entered the tableView cell turns green,the textField Text is set, and the textfield becomes uneditable.
My problem is that none of these settings save. I need it to remember if the question was answered correctly and change the cell accordingly. I know I can use Core Data or User Defaults to save things but i'm not sure how get the specific cells that were answered correctly to save.
My code below:
TableViewController
import UIKit
class TableViewController: UITableViewController, UITextFieldDelegate {
let questions = ["what is 3 + 5", "what is the meaning of life","what
is the number from the jim carrey movie"]
let answers = ["8","42","23"]
var textfieldColor = UIColor(red:0.98, green:0.23, blue:0.42,
alpha:1.0)
var textFieldText = ""
var isTextFieldEditable = true
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return answers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Answers", for: indexPath) as! TableViewCell
cell.question.text = questions[indexPath.row]
cell.backgroundColor = textfieldColor
cell.answerOutlet.text = textFieldText
cell.isUserInteractionEnabled = isTextFieldEditable
cell.answerOutlet.delegate = self
return cell
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
print(answers.contains(textField.text!))
if answers.contains(textField.text!)
{
textfieldColor = UIColor.green
textFieldText = textField.text!
isTextFieldEditable = false
let rowNumber = answers.index(of: textField.text!)
let indexPath = IndexPath(item: rowNumber!, section: 0)
tableView.reloadRows(at: [indexPath], with: .top)
}
return true
}
}
TableViewCell:
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var question: UILabel!
#IBAction func Answer(_ sender: UITextField)
{
}
#IBOutlet weak var answerOutlet: 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
}
}
Thank you for your help.
You can add a Boolean check that changes inside the function textFieldShouldReturn and store the value inside an array and save it, something like this:
correct[rowNumber!] = true
UserDefaults.standard.set(correct, forKey: "Correct")
Then, change the loading of the table in tableView using the array:
if correct[indexPath.row] == false {
cell.backgroundColor = textfieldColor1
cell.answerOutlet.text = textFieldText
cell.isUserInteractionEnabled = isTextFieldEditable
}
if correct[indexPath.row] == true {
cell.backgroundColor = textfieldColor2
cell.answerOutlet.text = answers[indexPath.row]
cell.isUserInteractionEnabled = false
}
and finally, check each time you load the view, inside viewDidLoad to see if there are any results stored in UserDefaults:
if let corretAnswers = UserDefaults.standard.object(forKey: "Correct") {
correct = corretAnswers as! [Bool]
}

get textfield in tableview cell when tap Save button and store in dictionary?

I have 2 section with each 16 rows,and how to get all textfield value in tableview cell? want to store it when I tap save button.
and I already retrive simulate data from firebase database put in String:AnyObject,and show it on tableview.
how to get value like textfield or switch in tableviewCell?
import UIKit
import Firebase
import FirebaseDatabaseUI
class SettingLabelTableViewController: UITableViewController, UITextFieldDelegate {
var BitArray:[String] = ["M0","M1","M2","M3","M4","M5","M6","M0","M8"
,"M9","M10","M11","M12","M13","M14","M15"]
var WordArray:[String] = ["D0","D1","D2","D3","D4","D5","D6","D0","D8"
,"D9","D10","D11","D12","D13","D14","D15"]
var DeviceKey:String?
var Ref: FIRDatabaseReference!
var dict = [String:AnyObject]()
var allCellsText = [String]()
#IBAction func SaveButton(_ sender: UIBarButtonItem)
{
/*self.Ref.setValue(dict, withCompletionBlock:
{ (error, dbref) in
})*/
}
override func viewDidLoad()
{
super.viewDidLoad()
Ref = device.child("DEVICE").child(DeviceKey!).child("SETTINGS").child("LABEL")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
Ref.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists(){
print("not exist")
csGolbal.g_NameAry.removeAll()
self.dict.removeAll()
}
else{
self.dict.removeAll()
self.dict = (snapshot.value as? [String: AnyObject])!
/*for item in snapshot.value as! [String : String]{
csGolbal.g_NameAry.append([item.key:item.value])
}*/
}
self.tableView.reloadData()
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if section == 0
{
return BitArray.count
}
else
{
return WordArray.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "LabelNameCell", for: indexPath) as! LabelNameTableViewCell
cell.LabelTitle.text = BitArray[indexPath.row]
if dict.count > 0{
cell.txtName.text = dict["M"+String(indexPath.row)] as? String ?? "null"
}
return cell
}
my tableviewCell
class LabelNameTableViewCell: UITableViewCell
{
#IBOutlet weak var LabelTitle: UILabel!
#IBOutlet weak var txtName: 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
}
}
You can do somthing like this
#IBAction func saveButton(_ sender: UIBarButtonItem) {
var dict: [String:String] = [:]
for (i,bit) in bitArray.enumarate() {
let cell = tableView.cellForRow(at: IndexPath(row: i, section: 0)) as! LabelNameTableViewCell
dict[bit] = cell.txtName.text
}
for (i,word) in wordArray.enumarate() {
let cell = tableView.cellForRow(at: IndexPath(row: i, section: 1)) as! LabelNameTableViewCell
dict[word] = cell.txtName.text
}
// dict ---- "M0": "some text" ...
//then store it
}
p.s. In swift variables and function must start with lowercase character, see apple standard library functions.

Table View Cell with a 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 a normal swift file but because this is a subclass, I'm not sure what to do. What I've tried is to use:
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
cell.entranceFeeTextField.delegate = self
entranceFeeAmount = cell.entranceFeeTextField.text!
}
This code doesn't run and I'm not exactly sure which textfield delegates I need to run in order to be able to get the Text value from the textfield.
You could use the UITextFieldDelegate methods textFieldShouldEndEditing(:) or textFieldShouldReturn(:) to get the results of the textfield.
for example:
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
print("TextField should end editing method called")
let textFromCell = textField.text!
//do whatever you want with the text!
return true;
}
In this code snippet, textField will actually be your instance of entranceFeeTextField. Because somewhere, when that textfield stops editing, it calls self.delegate?.textFieldShouldEndEditing(entranceFeeTextField) and that method's implementation is inside your CreateEventVC.
Returning true will allow the textfield to end editing. This method will only get called when the user wants to stop editing. So you should remove entranceFeeAmount = cell.entranceFeeTextField.text! from your cellForRowAtIndexPath method because that's where you create your cell. At that point a user will not have typed into your textfield, so no use in getting the text from it as soon as it has been made.
All you have to do is implement one of those methods in CreateEventVC.
Here is the full code: (Xcode 8 swift 3)
(View Controller Class)
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate
{
#IBOutlet weak var tbl: UITableView!
var cell = TableViewCell()
override func viewDidLoad()
{
super.viewDidLoad()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
cell = tbl.dequeueReusableCell(withIdentifier: "CELL") as! TableViewCell
cell.configure(text: "", placeholder: "EnterText")
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
print( cell.returnTextOfTextField() )
print(cell.txtField.text)
cell.txtField .resignFirstResponder()
return true
}
}
TableViewCell class (Custom cell):
class TableViewCell: UITableViewCell,UITextFieldDelegate
{
#IBOutlet weak var txtField: UITextField!
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
}
public func configure(text: String?, placeholder: String) {
txtField.text = text
txtField.placeholder = placeholder
txtField.accessibilityValue = text
txtField.accessibilityLabel = placeholder
}
func returnTextOfTextField() -> String
{
print(txtField.text)
return txtField.text!
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
"CELL" is the identifier given to cell in Nib .
This is working code , I get the value from text field and even keyboard is resigned.
var cell = TableViewCell() // customCell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
cell = tbl.dequeueReusableCell(withIdentifier: "CELL") as! TableViewCell
cell.configure(text: "", placeholder: "EnterText")
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
//cell = tbl.dequeueReusableCell(withIdentifier: "CELL") as! TableViewCell
print( cell.returnTextOfTextField() )
print(cell.txtField.text)
cell.txtField .resignFirstResponder()
return true
}
/// Custom cell class
class TableViewCell: UITableViewCell,UITextFieldDelegate
{
#IBOutlet weak var txtField: UITextField!
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
}
public func configure(text: String?, placeholder: String) {
txtField.text = text
txtField.placeholder = placeholder
txtField.accessibilityValue = text
txtField.accessibilityLabel = placeholder
}
func returnTextOfTextField() -> String
{
print(txtField.text)
return txtField.text!
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

custom cell delegate and UITextField (swift)

the goal is to create new table row every time any other row is tapped. all rows contain UITextField and that is the problem.
main controller:
var subtasksArray = ["one", "two"]
var addRow = 0
class AddEditTaskController: UIViewController, UITableViewDataSource,
UITableViewDelegate, CustomCellDelegate {
func reloadTable() {
subtaskTable.reloadData()
}
#IBOutlet weak var subtaskTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
var tblView = UIView(frame: CGRectZero)
subtaskTable.tableFooterView = tblView
subtaskTable.tableFooterView?.hidden = true
subtaskTable.backgroundColor = UIColor.clearColor()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return subtasksArray.count + addRow
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: SubtaskCell = subtaskTable.dequeueReusableCellWithIdentifier("subtaskCell") as SubtaskCell
cell.delegate = self
return cell
}
custom cell:
protocol CustomCellDelegate {
func reloadTable()
}
class SubtaskCell: UITableViewCell, UITextFieldDelegate {
var delegate: CustomCellDelegate?
#IBOutlet weak var subtaskTextField: UITextField!
var subtasksArray = [String]()
override func awakeFromNib() {
super.awakeFromNib()
subtaskTextField.delegate = self
}
func textFieldDidBeginEditing(textField: UITextField) {
addRow += 1
delegate?.reloadTable()
}
func textFieldDidEndEditing(textField: UITextField) {
subtasksArray.append(subtaskTextField.text)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
the problem is that if tap any row, a new one is created, but text field is not active.
if i don't use CustomCellDelegate, textfields in cells work fine, but i couldn't find any other way to reload table except cell delegate.

Resources