Reputation: 99
There is a scenario where I need to display data from a JSON in my table view cell with multiple data in the label, text field, text view..etc, after displaying I need to edit the text field and text view data from any cell, and once completed I need to send that values to the server side.
Please note: I do not know how many cells, as the data was fetched from the server end.
Please go through the image for a detailed description. These are the values in the cell like sl.no, date, time, record of the investigation.
I need to update the time and record of investigation in each cell where ever required.
In submit button which is at the bottom, I need an array of updated data from each cell.
cellforRowatIndexpath looks like this :
cell.sl.text = "Sl No."
cell.Date.text = "Date:"
cell.time.text = "Time:"
cell.some.text = "Some"
cell.record.text = "Record"
cell.txtVw.layer.borderColor = UIColor.lightGray.cgColor
cell.txtVw.layer.borderWidth = 1
cell.nosl.text = "\(indexPath.row + 1)"
cell.Datee.text = "28/04/2023"
cell.timeetxt.text = "12:00"
cell.somee.text = "Some content"
cell.txtVw.text = "Some editable text"
return cell
This is how my tableview looks after loading :
Please guide me how to modify the time "12:00" to "12:30" and "Some editable text" to "Something" and save it in each cell.
Advance thanks.
Upvotes: 0
Views: 318
Reputation: 99
With the help of chatGPT, I am able to resolve this. I am posting here because maybe it help others.
My ViewController class looks like this: -
class ViewController{
var dataSource: [DataModel] = []
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Fetch data from API
fetchData()
// Register table view cell
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
// Do any additional setup after loading the view.
}
func fetchData() {
// Simulating API call with hardcoded data
let apiData = [
["id": 1, "title": "Title 1", "description": "Description 1"],
["id": 2, "title": "Title 2", "description": "Description 2"],
["id": 3, "title": "Title 3", "description": "Description 3"],
["id": 1, "title": "Title 1", "description": "Description 1"],
["id": 2, "title": "Title 2", "description": "Description 2"],
["id": 3, "title": "Title 3", "description": "Description 3"],
["id": 1, "title": "Title 1", "description": "Description 1"],
["id": 2, "title": "Title 2", "description": "Description 2"],
["id": 3, "title": "Title 3", "description": "Description 3"],
["id": 1, "title": "Title 1", "description": "Description 1"],
["id": 2, "title": "Title 2", "description": "Description 2"],
["id": 3, "title": "Title 3", "description": "Description 3"]
]
// Parse API data into DataModel objects
dataSource = apiData.compactMap { DataModel(dictionary: $0) }
// Reload table view
tableView.reloadData()
}
// Save button action
@objc func saveButtonTapped(_ sender: UIButton) {
guard let cell = sender.superview?.superview as? CustomTableViewCell,
let indexPath = tableView.indexPath(for: cell) else {
return
}
// Update data source with the latest text from the text field and text view
let newData = DataModel(id: dataSource[indexPath.row].id,
title: cell.titleTextField.text ?? "",
description: cell.descriptionTextView.text ?? "")
dataSource[indexPath.row] = newData
// Reload the table view to reflect the changes
tableView.reloadData()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath:
IndexPath) -> CGFloat {
return 200
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section:
Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath) as! CustomTableViewCell
// Configure the cell
let data = dataSource[indexPath.row]
cell.configure(with: data)
cell.saveButton.addTarget(self, action: #selector(saveButtonTapped),
for: .touchUpInside)
return cell
}
}
}
My TableViewCell : --
import UIKit
class CustomTableViewCell: UITableViewCell {
let titleTextField: UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.placeholder = "Title"
return textField
}()
let descriptionTextView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.isScrollEnabled = false
textView.font = UIFont.systemFont(ofSize: 14)
return textView
}()
let saveButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Save", for: .normal)
return button
}()
var data: DataModel?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupSubviews()
setupConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupSubviews()
setupConstraints()
}
func setupSubviews() {
contentView.addSubview(titleTextField)
contentView.addSubview(descriptionTextView)
contentView.addSubview(saveButton)
}
func setupConstraints() {
NSLayoutConstraint.activate([
titleTextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
titleTextField.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
titleTextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
titleTextField.heightAnchor.constraint(equalToConstant: 30),
descriptionTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
descriptionTextView.topAnchor.constraint(equalTo: titleTextField.bottomAnchor, constant: 8),
descriptionTextView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
descriptionTextView.heightAnchor.constraint(equalToConstant: 80),
saveButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
saveButton.topAnchor.constraint(equalTo: descriptionTextView.bottomAnchor, constant: 8)
])
}
func configure(with data: DataModel) {
self.data = data
titleTextField.text = data.title
descriptionTextView.text = data.description
}
}
My Model : -
import Foundation
struct DataModel {
let id: Int
let title: String
let description: String
init(id: Int, title: String, description: String) {
self.id = id
self.title = title
self.description = description
}
init?(dictionary: [String: Any]) {
guard let id = dictionary["id"] as? Int,
let title = dictionary["title"] as? String,
let description = dictionary["description"] as? String else {
return nil
}
self.init(id: id, title: title, description: description)
}
}
Upvotes: 0
Reputation: 169
The code I'm about to paste is a rough draft, but should point you in the right direction. Don't expect this to work if you copy and paste.
//Store your data.
struct Item {
var time: String
var record: String
}
class CustomCell: UITableViewCell {
// MARK: - Properties
private let textField = UITextField() // or outlet
private let textView = UITextView() // or outlet
var textFieldTextDidChange: ((String?) -> Void)?
var textViewTextDidChange: ((String?) -> Void)?
// MARK: - Initialization
override func awakeFromNib() {
// Configure the text field
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
textView.delegate = self
}
// MARK: - Actions
@objc private func textFieldDidChange(_ textField: UITextField) {
textFieldTextDidChange?(textField.text)
}
// MARK: - UITextViewDelegate
func textViewDidChange(_ textView: UITextView) {
textViewTextDidChange?(textView.text)
}
}
class TestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var dataDictionary = [Int: Item]()
var tableView = UITableView()
override func viewDidLoad() {
tableView.delegate = self
tableView.dataSource = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = CustomCell()
cell.textFieldTextDidChange = { [weak self] text in
dataDictionary[indexPath.row]?.time = text
}
cell.textViewTextDidChange = { [weak self] text in
self?.dataDictionary[indexPath.row]?.record = text ?? ""
}
return cell
}
}
Upvotes: 0