Daniel
Daniel

Reputation: 19

Passing data from Container View

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

Answers (1)

Sumesh Sivan
Sumesh Sivan

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

Related Questions