Reputation: 19
I am not too sure what I am supposed to do next.
I have a view controller AddRecipeViewController which has 4 container views added. They are also nested in a segment controller. Everything works from the UI.
What I want to do is save the text that is inputted in the tableviewcell (UITextFields)
If you could help me understand what I’m missing, that would really help me out! AddRecipeChild has a tableView with 4 custom cells.
class AddRecipeViewController: UIViewController {
@IBOutlet weak var AddRecipeChild: UIView!
@IBOutlet weak var ingredientsChild: UIView!
@IBOutlet weak var directionsChild: UIView!
@IBOutlet weak var photoChild: UIView!
@IBOutlet weak var saveButton: UIBarButtonItem!
@IBOutlet weak var segmented: UISegmentedControl!
let db = Firestore.firestore()
var id = UUID().uuidString
let user = Auth.auth().currentUser?.email
var objRecipe: RecipeData!
var addRecipe: AddRecipeChildVC!
var addIngredients: IngredientsChildVC!
var addDirections: DirectionsChildVC!
var addPhoto: PhotoChildVC!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
self.navigationItem.leftBarButtonItem = newBackButton
objRecipe = RecipeData(user: user ?? "", recipeName: "", ingredientsText: "", directionsText: "", prepTime: "", cookTime: "", image: "", servingsNumber: "")
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.ingredientsChild.isHidden = true
self.directionsChild.isHidden = true
self.photoChild.isHidden = true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? AddRecipeChildVC,
segue.identifier == "addRec" {
self.addRecipe = vc
}
if let vc = segue.destination as? IngredientsChildVC,
segue.identifier == "addIn" {
self.addIngredients = vc
}
if let vc = segue.destination as? DirectionsChildVC,
segue.identifier == "addDi" {
self.addDirections = vc
}
if let vc = segue.destination as? PhotoChildVC,
segue.identifier == "addPh" {
self.addPhoto = vc
}
}
@IBAction func segmentChanged(_ sender: UISegmentedControl) {
self.AddRecipeChild.isHidden = true
self.ingredientsChild.isHidden = true
self.directionsChild.isHidden = true
self.photoChild.isHidden = true
switch segmented.selectedSegmentIndex {
case 0:
self.AddRecipeChild.isHidden = false
case 1:
self.ingredientsChild.isHidden = false
case 2:
self.directionsChild.isHidden = false
case 3:
self.photoChild.isHidden = false
default:
self.AddRecipeChild.isHidden = false
}
}
@objc func cancelPressed(sender: UIBarButtonItem) {
navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
}
@IBAction func savePressed(_ sender: UIBarButtonItem) {
AppDelegate.shared.dataHandler.save(recipe: objRecipe)
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "home") as! HomeScreenViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
extension AddRecipeViewController: childToParentProtocol {
func needToPassInfoToParent(with value: String) {
}
}
protocol childToParentProtocol: AnyObject {
func needToPassInfoToParent(with value: String)
}
class AddRecipeChildVC: UIViewController {
@IBOutlet weak var table: UITableView!
var objRecipe: RecipeData!
weak var delegate: childToParentProtocol? = nil
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
table.register(UINib(nibName: "RecipeNameCell", bundle: nil), forCellReuseIdentifier: "recipeName")
table.register(UINib(nibName: "ServingSizeTableViewCell", bundle: nil), forCellReuseIdentifier: "servings")
table.register(UINib(nibName: "PrepTimeTableViewCell", bundle: nil), forCellReuseIdentifier: "prep")
table.register(UINib(nibName: "CookTimeTableViewCell", bundle: nil), forCellReuseIdentifier: "cook")
table.register(UINib(nibName: "IngredientsTextCell", bundle: nil), forCellReuseIdentifier: "ingredients")
}
}
extension AddRecipeChildVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = table.dequeueReusableCell(withIdentifier: "recipeName", for: indexPath) as! RecipeNameCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 1 {
let cell = table.dequeueReusableCell(withIdentifier: "servings", for: indexPath) as! ServingSizeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 2 {
let cell = table.dequeueReusableCell(withIdentifier: "prep", for: indexPath) as! PrepTimeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 3 {
let cell = table.dequeueReusableCell(withIdentifier: "cook", for: indexPath) as! CookTimeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else {
let cell = table.dequeueReusableCell(withIdentifier: "recipeName", for: indexPath) as! RecipeNameCell
return cell
}
}
}
extension AddRecipeChildVC: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
switch textField.tag {
case 0:
let recipeName = textField.text ?? ""
print(recipeName)
objRecipe.recipeName = textField.text!
case 1:
let servingSize = textField.text ?? ""
print(servingSize)
objRecipe.servingsNumber = textField.text!
case 2:
let prepTime = textField.text ?? ""
print(prepTime)
objRecipe.prepTime = textField.text!
case 3:
let cookTime = textField.text ?? ""
print(cookTime)
objRecipe.cookTime = textField.text!
default:
break
}
}
}
struct DataHandler {
var db: Firestore
init() {
FirebaseApp.configure()
self.db = Firestore.firestore()
}
func save(recipe: RecipeData) {
let new = db.collection("Recipe").document(recipe.id)
new.setData([
"recipeName": recipe.recipeName,
"user": recipe.user,
"prep": recipe.prepTime,
"cook": recipe.cookTime,
"servings": recipe.servingsNumber,
"ingredients": recipe.ingredientsText,
"directions": recipe.directionsText
])
print("This is printing: \(new)")
}
func load() -> [RecipeData] {
var recipes = [RecipeData]()
db.collection("Recipe")
.addSnapshotListener { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let data = document.data()
guard data.count > 0 else {
break
}
let recipeName = data["recipeName"] as! String
let user = data["user"] as! String
let servings = data["servings"] as! String
let cook = data["cook"] as! String
let prep = data["prep"] as! String
let ingredients = data["ingredients"] as! String
let directions = data["directions"] as! String
let newRecipe = RecipeData(user: user, recipeName: recipeName, ingredientsText: ingredients, directionsText: directions, prepTime: prep, cookTime: cook, image: "", servingsNumber: servings)
recipes.append(newRecipe)
}
}
}
return recipes
}
}
Upvotes: 1
Views: 68
Reputation: 213
When you are setting the delegate for textField of the cell to self like cell.textField.delegate = self
here self
is actually is the AddRecipeChildVC
. So the delegate call will be received by AddRecipeChildVC
instead of AddRecipeViewController
.
You need to change
extension AddRecipeViewController: UITextFieldDelegate {
....
}
to
extension AddRecipeChildVC: UITextFieldDelegate {
....
}
Then add a objRecipe
declaration in AddRecipeChildVC
class AddRecipeChildVC: UIViewController, UITextFieldDelegate {
var objRecipe = RecipeData.init()
...
}
Finally in sendToFirebase()
function use
let data = try JSONEncoder().encode(addRecipe.objRecipe)
Instead of the last step, you can also pass the objRecipe
to AddRecipeViewController
using AddRecipeDelegate
as well.
Upvotes: 0