This question might be very broad but I can't find any similar approaches. I have a tableView that consists of several sections. It's like a profile page where user can edit their bio i.e. name, date of birth, gender etc. As the bio is separated into different sections. How would I get all the data to be saved at once when tapped in the tableViewController and NOT the tableViewCell's.
I'm used to sending data from TableViewController to a TableViewCell to populate the cells. But I now need the opposite action where the data from TableViewCell gets sent back to the TableViewController in order for me to define what to save to the database.
Here is an example of how I would save in a normal ViewController:
func saveData() {
guard let firstNameText = firstNameField.text, let lastNameText = lastNameField.text else { return }
guard let uid = Auth.auth().currentUser else { return }
let databseRef = Database.database().reference(withPath: "users/\(uid)")
let bioItem: [String : Any] = ["firstName" : firstNameText, "lastName" : lastNameText]
databseRef.updateChildValues(bioItem)
}
Update
Here is what I have attempted using the solution suggested below:
protocol TextFieldCellDelegate: class {
func textFieldCell(_ cell: FirstNameCell, didChangeText text: String)
}
class FirstNameCell: UITableViewCell {
weak var delegate: TextFieldCellDelegate?
var indexPath: IndexPath!
var user: User? {
didSet {
guard let user = user else { return }
nameField.text = user.firstName
}
}
lazy var nameField: UITextField = {
let field = UITextField()
return field
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setupViews() {
addSubview(nameField)
// Adding constraints...
}
@objc private func textFieldDidChange(_ textField: UITextField) {
guard let text = nameField.text else {
return
}
delegate?.textFieldCell(self, didChangeText: text)
}
}
ViewController:
var user: User!
func textFieldCell(_ cell: FirstNameCell, didChangeText text: String) {
switch cell.indexPath.section {
case 0:
if cell.indexPath.row == 0 {
user.firstName = text
print("New name: \(text)")
}
// handle other rows
default:
break
// handle other sections and rows
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch (indexPath.section) {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: firstNameCell, for: indexPath) as! FirstNameCell
cell.user = self.user
cell.delegate = self //error
cell.indexPath = indexPath
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: secondNameCell, for: indexPath) as! SecondNameCell
cell.user = self.user
return cell
default:
break
}
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}