I am new to coding and do not understand how to word things properly and how to clean up my code but here goes.
I have a view controller. In the view controller I have a view with a view and a tableview. In the view, I have an UIImage with tap gestures enabled and three textfields. In the nav bar, I have a nav UIButton. When the nav UIButton is tapped the information in the text fields as well as the image is sent to my storage database.
Inside the the table view I have a prototype cell. In the prototype cell I have four text fields. These textfields are constrained by setting a tableviewcell class. That code looks like the following:
import UIKit
import Firebase
class ConsiderationsCell: UITableViewCell {
@IBOutlet weak var nameTextFieldConsiderations: UITextField!
@IBOutlet weak var feedTextFieldConsiderations: UITextField!
@IBOutlet weak var storyTextFieldConsiderations: UITextField!
@IBOutlet weak var compensationTextFieldConsiderations: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
nameTextFieldConsiderations.placeholder = "Name"
nameTextFieldConsiderations.font = UIFont.systemFont(ofSize: 16)
nameTextFieldConsiderations.translatesAutoresizingMaskIntoConstraints = false
nameTextFieldConsiderations.backgroundColor = UIColor.secondarySystemBackground
nameTextFieldConsiderations.textColor = .label
let nameTFC = nameTextFieldConsiderations.text
feedTextFieldConsiderations.placeholder = "#"
feedTextFieldConsiderations.font = UIFont.systemFont(ofSize: 16)
feedTextFieldConsiderations.translatesAutoresizingMaskIntoConstraints = false
feedTextFieldConsiderations.backgroundColor = UIColor.secondarySystemBackground
feedTextFieldConsiderations.textColor = .label
storyTextFieldConsiderations.placeholder = "#"
storyTextFieldConsiderations.font = UIFont.systemFont(ofSize: 16)
storyTextFieldConsiderations.translatesAutoresizingMaskIntoConstraints = false
storyTextFieldConsiderations.backgroundColor = UIColor.secondarySystemBackground
storyTextFieldConsiderations.textColor = .label
compensationTextFieldConsiderations.placeholder = "$"
compensationTextFieldConsiderations.font = UIFont.systemFont(ofSize: 16)
compensationTextFieldConsiderations.translatesAutoresizingMaskIntoConstraints = false
compensationTextFieldConsiderations.backgroundColor = UIColor.secondarySystemBackground
compensationTextFieldConsiderations.textColor = .label
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
I have a send function right now that is sending data from the first row to my firebase database. The code for that function is the following:
import UIKit
import Firebase
class ConsiderationsViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var tableView: UITableView!
var numberOfPeople: [String] = []
var AddPersonCell = "AddPersonCell"
@IBOutlet weak var CompanyImage: UIImageView!
@IBOutlet weak var companyNameTextFieldConsiderations: UITextField!
@IBOutlet weak var companyDescriptionTextFieldConsiderations: UITextField!
@IBOutlet weak var startDateTextFieldConsiderations: UITextField!
@IBOutlet weak var endDateTextFieldConsiderations: UITextField!
let datePickerS = UIDatePicker()
let datePickerE = UIDatePicker()
var database: Database!
var storage: Storage!
var selectedImage: UIImage?
var ref:DatabaseReference?
var databaseHandle:DatabaseHandle = 0
let dbref = Database.database().reference()
let uid = Auth.auth().currentUser?.uid
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.companyNameTextFieldConsiderations.delegate = self
self.companyDescriptionTextFieldConsiderations.delegate = self
// Set the Firebase reference
ref = Database.database().reference()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ConsiderationsViewController.handleSelectCompanyImageView))
CompanyImage.addGestureRecognizer(tapGesture)
CompanyImage.isUserInteractionEnabled = true
self.navigationController!.navigationBar.isTranslucent = false
navigationItem.backBarButtonItem = UIBarButtonItem(
title: "", style: .plain, target: nil, action: nil)
createDatePickerForStart()
createDatePickerForEnd()
}
@objc func handleSelectCompanyImageView() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.allowsEditing = true
present(pickerController, animated: true, completion: nil)
}
@IBAction func AddPersonTapped(_ sender: Any) {
numberOfPeople.append("#")
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
@IBAction func sendButtonTapped(_ sender: Any) {
let companyNameC = companyNameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let companyDescriptionC = companyDescriptionTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let today = Date()
let formatter1 = DateFormatter()
formatter1.dateFormat = "MMM d y"
print(formatter1.string(from: today))
let todaysDate = formatter1.string(from: today)
let storageRef = Storage.storage().reference(forURL: "MY STORAGE URL HERE")
let imageName = companyNameTextFieldConsiderations.text!
let storageCompanyRef = storageRef.child("Company_Image_Considerations").child("\(todaysDate)").child(imageName)
let companyDescriptionTextFieldText = companyDescriptionTextFieldConsiderations.text
let dateToStart = startDateTextFieldConsiderations.text
let dateToDecide = endDateTextFieldConsiderations.text
let companyRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName)
let index = IndexPath(row: 0,section: 0)
let cell = tableView.cellForRow(at:index) as! ConsiderationsCell
let nameTFC = cell.nameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let feedTFC = cell.feedTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let storyTFC = cell.storyTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let compensationTFC = cell.compensationTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let values = ["Feed_Quantity": feedTFC, "Story_Quantity": storyTFC, "Compensation": compensationTFC]
let considerationInfluencerRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName).child("Users").child("\(nameTFC)")
guard let imageSelected = self.CompanyImage.image else {
print ("Avatar is nil")
return
}
var dict: Dictionary<String, Any> = [
"Company Image": "",
"Company Description": companyDescriptionTextFieldText!,
"Start Date": dateToStart!,
"Decision Date": dateToDecide! ]
guard let imageData = imageSelected.jpegData(compressionQuality: 0.5) else {
return
}
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
storageCompanyRef.putData(imageData, metadata: metadata, completion:
{ (StorageMetadata, error) in
if (error != nil) {
return
}
storageCompanyRef.downloadURL { (url, error) in
if let metadateImage = url?.absoluteString {
dict["Company Image"] = metadateImage
companyRef.updateChildValues(dict, withCompletionBlock: {
(error, ref) in
if error == nil {
print("Done")
return
}
}
)
}
}
storageRef.updateMetadata(metadata) { metadata, error in
if error != nil {
//Uh-oh, an error occurred!
} else {
// Updated metadata for 'images/forest.jpg' is returned
}
}
})
considerationInfluencerRef.updateChildValues(values as [AnyHashable : Any]) { (error, ref) in
if error != nil {
print(error ?? "")
return
}
self.navigationController?.popViewController(animated: true)
}
}
func createDatePickerForStart() {
// center text in field
startDateTextFieldConsiderations.textAlignment = .center
// toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
// barbutton
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedStart))
toolbar.setItems([doneButton], animated: true)
// assign toolbar to textfield
startDateTextFieldConsiderations.inputAccessoryView = toolbar
// assign datePicker to text field
startDateTextFieldConsiderations.inputView = datePickerS
// date picker mode
datePickerS.datePickerMode = .date
}
func createDatePickerForEnd() {
// center text in field
endDateTextFieldConsiderations.textAlignment = .center
// toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
// barbutton
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedEnd))
toolbar.setItems([doneButton], animated: true)
// assign toolbar to textfield
endDateTextFieldConsiderations.inputAccessoryView = toolbar
// assign datePicker to text field
endDateTextFieldConsiderations.inputView = datePickerE
// date picker mode
datePickerE.datePickerMode = .dateAndTime
}
@objc func donePressedStart() {
// formatter
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
startDateTextFieldConsiderations.text = formatter.string(from: datePickerS.date)
self.view.endEditing(true)
}
@objc func donePressedEnd() {
// formatter
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .medium
endDateTextFieldConsiderations.text = formatter.string(from: datePickerE.date)
self.view.endEditing(true)
}
}
extension ConsiderationsViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//print("did Finish Picking Media")
if let image = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerEditedImage")] as? UIImage{
selectedImage = image
CompanyImage.image = image
}
dismiss(animated: true, completion: nil)
}
}
extension ConsiderationsViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfPeople.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: AddPersonCell, for: indexPath) as! ConsiderationsCell
return cell
}
}
I am able to get the first row text field sent using this function and it looks like the following in my database:
I can send the second row but I have to change the index path to:
let index = IndexPath(row: 1,section: 0)
I would like to have each row to add the name textfield name under each user node. I would also like the feed, story, and compensation textfields in each row to be under each name textfield node that they correspond to.
If there is a better way to do this I am all years. I have been trying to do this for the last 2 weeks.
(In the future I will need help with the name textfield corresponding to a specific user in my database and be able to show them the company information as well as their specific node information)
Please help!!!
I needed to set the labels equal to their corresponding textfields for their correct indexPath.row. Here is the code I ended up using:
extension ConsiderationsTestViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ConsiderationsTestViewController.people.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: AddPersonCell, for: indexPath) as! ConsiderationsCell
let numberOfPeopleCells = ConsiderationsTestViewController.people[indexPath.row]
cell.nameLabelC.text = numberOfPeopleCells.Name
cell.feedLabelC.text = numberOfPeopleCells.PostNumber
cell.storyLabelC.text = numberOfPeopleCells.StoryNumber
cell.compensationLabelC.text = numberOfPeopleCells.Compensation
cell.userImage.loadImageUsingCacheWithUrlString(urlString: numberOfPeopleCells.ProfileImageUrl!)
cell.userImage.layer.cornerRadius = 25
cell.nameLabelC.numberOfLines = 0
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
ConsiderationsTestViewController.people.remove(at: indexPath.row)
// handle delete (by removing the data from your array and updating the tableview)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
}