Add Text Label and Button to dynamic tableview cell programmatically with Swift
You can implement like this
let titleArray = ["a", "b", "c"]
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return no.of cell do you want
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cellHeight = tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: indexPath.row, inSection: indexPath.section))
var cell = CustomCell(frame: CGRectMake(0, 0, self.view.frame.width, cellHeight), title: titleArray[indexPath.row])
cell.cellLabel.text = //labelText
cell.cellButton.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
class CustomCell: UITableViewCell {
var cellButton: UIButton!
var cellLabel: UILabel!
init(frame: CGRect, title: String) {
super.init(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
cellLabel= UILabel(frame: CGRectMake(self.frame.width - 100, 10, 100.0, 40))
cellLabel.textColor = UIColor.blackColor()
cellLabel.font = //set font here
cellButton = UIButton(frame: CGRectMake(5, 5, 50, 30))
cellButton.setTitle(title, forState: UIControlState.Normal)
addSubview(cellLabel)
addSubview(cellButton)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
}
Add button to uitableview cell programmatically
Create a subclass of UITableViewcell -
class MyCell: UITableViewCell {
var buttonTapCallback: () -> () = { }
let button: UIButton = {
let btn = UIButton()
btn.setTitle("Button", for: .normal)
btn.backgroundColor = .systemPink
btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
return btn
}()
let label: UILabel = {
let lbl = UILabel()
lbl.font = UIFont.systemFont(ofSize: 16)
lbl.textColor = .systemPink
return lbl
}()
@objc func didTapButton() {
buttonTapCallback()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//Add button
contentView.addSubview(button)
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
//Set constraints as per your requirements
button.translatesAutoresizingMaskIntoConstraints = false
button.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
button.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
button.widthAnchor.constraint(equalToConstant: 100).isActive = true
button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
//Add label
contentView.addSubview(label)
//Set constraints as per your requirements
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: button.trailingAnchor, constant: 20).isActive = true
label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Now in your view controller register this cell -
myTableView.register(MyCell.self, forCellReuseIdentifier: "MyCell")
Now load this cell using cellForRowAt method -
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
cell.label.text = ""
cell.buttonTapCallback = {
cell.label.text = "Hi"
}
return cell
}
Add a Text Field to A UITableViewCell in swift
The text field frame should be with in cell size and check your datasource also
use
cell.contentView.addSubview(tf)
instead of cell.addSubview(tf)
The default height is 44, if you want more then implement respective delegate
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
add code at last
class customCell: UITableViewCell {
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
}
}
Then change your code:
let cell: customCell = self.extraGuestsTable.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as customCell!
let tf = UITextField(frame: CGRect(x: 20, y: 0, width: 300, height: 20))
tf.placeholder = "Enter text here"
tf.font = UIFont.systemFont(ofSize: 15)
//cell.contentView.addSubview(tf)
cell.addSubview(tf)
return cell
Dynamically adding a custom UITableViewCell
Firstly, you have to subclass UITableViewCell for a UITableViewCell with UITextField. Of course you can add the UITextField inside cellForRowAt delegate function but I prefer to do it with a custom UITableViewCell.
class UITableViewCellWithTextField: UITableViewCell {
var textField: UITextField!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
func setup() {
let textField = UITextField(frame: self.contentView.frame)
self.contentView.addSubview(self.textField)
}
}
Next, you have to register this custom UITableViewCell into your UITableView. Add this to your existing UITableViewCell registration line of code.
jobTableView.register(UITableViewCell.self, forCellReuseIdentifier: tableCell)
jobTableView.register(UITableViewCellWithTextField.self, forCellReuseIdentifier: "TextFieldCell")
The next step is to declare a variable to indicate that the user has initiated the add new job function.
public class MiddlePartCell: BaseCell, UITableViewDelegate, UITableViewDataSource {
var isHandlingAddJob = false
...
}
Then in your handleAddJob function
func handleAddJob(){
self.isHandlingAddJob = true
datas.insert("new data", at: 0)
jobTableView.beginUpdates()
jobTableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
jobTableView.endUpdates()
}
Lastly is to let the UITableView know that the incoming new cell to handle adding of a new job, and should use the custom text field cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 && self.isHandlingAddJob {
// Handling new job cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as! UITableViewCellWithTextField
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: tableCell, for: indexPath)
cell.textLabel?.text = datas[indexPath.item]
return cell
}
P.S. Hope I'm understanding your question correctly lol.
To persist the data of the text field in the custom table view cell, you have to use the delegate pattern. Firstly, you have to either conform your custom table view cell or MiddlePartCell class to UITextFieldDelegate. I will be going for the latter.
class MiddlePartCell: BaseCell, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
...
}
Then in your cellForRowAt function, you set your custom cell's text field delegate to your MiddlePartCell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 && self.isHandlingAddJob {
// Handling new job cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as! UITableViewCellWithTextField
cell.returnKeyType = .Done
cell.textField.delegate = self
return cell
}
...
}
Lastly, use the UITextFieldDelegate function. When the use click done on the keyboard, your cell will be reloaded to be a normal UITableViewCell without UITextField.
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.isHandlingAddJob = false
self.datas.first! = textField.text!
self.jobTableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 0, inSection: 0)], withRowAnimation: .Automatic)
return true
}
Dynamically change cell height according to label text
The bottom anchor needs to be set:
cevapLabel.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
Send label text data with segue in TableView in Swift
I've finally done that using this example: Passing data between two UIViewControllers using Swift and Storyboard
It's make a lot easier and helps me finally get it to work!
Thanks!
Dynamic Custom TableView Cell swift
A dynamic table view can be accomplished with an appropriate data model.
For example use an enum for the kind and a struct with a member to indicate the kind
enum CellKind {
case image, label, picker
}
struct Model {
let kind : CellKind
// other struct members
}
How many cells are displayed depends on the items in the data source array
var items = [Model]()
In numberOfRows
return the number of items
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
In cellForRow
display the cells depending on the kind rather than on the index path
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.row]
switch item.kind {
case .image:
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell") as! ImageCell
// Set up cell.image
return cell
case .label:
let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell") as! LabelCell
// Set up cell.label
return cell
case .picker:
let cell = tableView.dequeueReusableCell(withIdentifier: "pickerCell") as! PickerCell
// Set up cell.picker
return cell
}
}
Show labels with dynamic sizes like a table without overlapping
Each of your textField should have the parameter "line" as 0 as follow:
or programmatically
@IBOutlet weak var text: UITextField!
[...]
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
text.numberOfLines = 0
}
This allow your textField to use an unlimited number of lines.
After that you have to play with autolayout to set constraint between your field.
Related Topics
Sending Whatsapp Message to a Specific Contact Number (Swift Project)
Easiest Way to Find Square Root in Swift
Swift Combine - Wait for All Publishers
"An Error Occurred While Accessing the Keychain" When Signing in Using Firebase
How Are the Arkit People Occlusion Samples Being Done
Is There No Default(T) in Swift
How to Set an Ordered Relationship with Nspersistentcloudkitcontainer
Swiftui MACos Nswindow Instance
Passing Data Between Two Nsoperations
Swift - Initialize View Controller from Storyboard by Overriding Init
Swift 2.0 Constraintswithvisualformat
Swift: How to Disable User Interaction While Touch Action Is Being Carried Out
How to Specify That a Generic Is a Value Type
How to Cancel Alamofire.Upload
Optional Chaining with Swift Strings