Search code examples
swiftcore-datasumuikittableview

add together the same core data item from multiple tableviews in UIKit


I have added a diagram below. What you can see in the diagram is a class where you save a food item. You click on the tableview cell and you can see a new class where you place the item and the amount you need to make that recipe. What I want to do is when you click on a tableview cell on the 2nd class. It searches throughout all the recipes to find the cumulative amount of that specific ingredient. In the diagram you can see that I highlighted apples. On the tableview cell it should be for example the apple hits 3.0, total all 8.0

example

core data

import UIKit

class Ingriendentsx: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        specifcGame.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomOneTableViewCell
        
        if cell == nil {
            cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell") as? CustomOneTableViewCell
        }
        
        let expense = specifcGame[indexPath.row]
        
    
        
        
        
        
        cell?.textLabel?.text = "\(expense.name!) hits \(expense.amount)"
        
        return cell ?? UITableViewCell()
    }
    
    
    var txt = UITextField()
    var btn = UIButton()
    var tble = UITableView()
    var lbl = UILabel()
    var txt2 = UITextField()
    var backB = UIButton()
    
    
    
    var ingreidentsAndAmount = [Ingriendents]()
    
    var inital : Recipe?
    var placeholder = String()
    
    private var specifcGame : [Ingriendents] = []
    
    
    
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        
        if let budget = inital {
            lbl.text = budget.recipeName
            
            //
            
            if let aE = budget.ir?.allObjects as? [Ingriendents] {
                specifcGame = aE
            }
            
            
            
        }
        
        
        
        
        [txt,btn, tble, lbl, txt2, backB].forEach {
            view.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
            $0.layer.borderWidth = 1
            $0.backgroundColor = UIColor(
                red: .random(in: 0.5...0.7),
                green: .random(in: 0.0...1),
                blue: .random(in: 0.3...0.5),
                alpha: 1
            )
            
            $0.layer.borderWidth = 1
            
            if let textfield = $0 as? UITextField {
                
                textfield.textAlignment = .center
            }
            
            if let label = $0 as? UILabel {
                
                label.textAlignment = .center
            }
            if let button = $0 as? UIButton {
                button.setTitleColor(.black, for: .normal)
            }
            
        }//below
        NSLayoutConstraint.activate([
            
            lbl.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            lbl.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05, constant: 0),
            lbl.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            lbl.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            
            
            txt.topAnchor.constraint(equalTo: lbl.bottomAnchor),
            txt.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05, constant: 0),
            txt.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            txt.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            txt2.topAnchor.constraint(equalTo: txt.bottomAnchor),
            txt2.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05, constant: 0),
            txt2.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            txt2.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            
            
            btn.topAnchor.constraint(equalTo: txt2.bottomAnchor),
            btn.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10, constant: 0),
            btn.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            btn.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            
            tble.topAnchor.constraint(equalTo: btn.bottomAnchor),
            tble.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.50, constant: 0),
            tble.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            tble.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            backB.topAnchor.constraint(equalTo: tble.bottomAnchor),
            backB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10, constant: 0),
            backB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            backB.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            
            
        ])
        tble.delegate = self
        tble.dataSource = self
        
        btn.addTarget(self, action: #selector(pressA), for: .touchDown)
        tble.register(CustomOneTableViewCell.self, forCellReuseIdentifier: "Cell")
        
        backB.addTarget(self, action: #selector(backer), for: .touchDown)
    }
    
    @objc func pressA(){
        guard let name = txt.text else {
            return
        }
        
        
        
        guard let calorieText = txt2.text, let count = Double(calorieText) else {
            return
        }

        
        guard let budget = inital else {
            return
        }
        
        
        
        
        
        let expense = DataManager.shared.saveToAttempts(name: name, amount: count, inz: budget)
        
        
        
        specifcGame.append(expense)
        
        tble.reloadData()
        DataManager.shared.save()
        txt.text = ""
        txt2.text = ""
        

    }
    
    @objc func backer(){
        self.dismiss(animated: true)
    }
    

}

class CustomOneTableViewCell: UITableViewCell {
    
    
}

Solution

  • func loadIngredients() has the logic for calculating total amount

    class IngredientsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        
        struct IngredientDetail {
            let ingredient: Ingredient
            let totalAmount: Double
        }
        
        @IBOutlet weak var name: UITextField!
        @IBOutlet weak var amount: UITextField!
        @IBOutlet weak var addButton: UIButton!
        @IBOutlet weak var tableView: UITableView!
        
        var recipe: Recipe!
        var ingredientsDetail: [IngredientDetail] = []
        
        override func viewDidLoad() {
            super.viewDidLoad()
            configureTableView()
            loadIngredients()
            navigationItem.title = recipe.recipeName
        }
        
        func configureTableView() {
            tableView.dataSource = self
            tableView.delegate = self
        }
        
        func loadIngredients() {
            let ingredientsFetchRequest = NSFetchRequest<Ingredient>(entityName: "Ingredient")
            
            if var fetchedAllIngredients = try? PersistenceController.shared.persistentContainer.viewContext.fetch(ingredientsFetchRequest) {
                
                // reset ingredientsDetail
                ingredientsDetail = []
                
                // filtering current recipe ingredients
                let recipeIngredients = fetchedAllIngredients.filter({ $0.recipe == recipe })
                
                for recipeIngredient in recipeIngredients {
                    
                    var totalAmount: Double = 0
                    
                    // name matching ingredients and calculating total amount
                    // filtering to avoid rechecking matched ingredients
                    fetchedAllIngredients = fetchedAllIngredients.filter({
                        if $0.name!.caseInsensitiveCompare(recipeIngredient.name!) == .orderedSame {
                            totalAmount += $0.amount
                            return false
                        }
                        return true
                    })
                    
                    ingredientsDetail.append(
                        IngredientDetail(
                            ingredient: recipeIngredient,
                            totalAmount: totalAmount
                        )
                    )
                }
                
            }
        }
        
        @IBAction func tappedAddIngredient() {
            if let ingredientName = name.text,
               !ingredientName.isEmpty,
               let amountText = amount.text,
               let amountDoubleValue = Double(amountText) {
                let ingredient = Ingredient(context: PersistenceController.shared.persistentContainer.viewContext)
                ingredient.name = ingredientName
                ingredient.amount = amountDoubleValue
                ingredient.recipe = recipe
                PersistenceController.shared.saveContext()
                loadIngredients()
                tableView.reloadData()
                name.text = ""
                amount.text = ""
            }
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            ingredientsDetail.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
            var content = cell.defaultContentConfiguration()
            let ingredientDetail = ingredientsDetail[indexPath.row]
            if ingredientDetail.totalAmount > ingredientDetail.ingredient.amount {
                let attributedText = NSMutableAttributedString(string: "Name: \(ingredientDetail.ingredient.name!), Amount: \(ingredientDetail.ingredient.amount)")
                let boldAttributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 15, weight: .bold)]
                let totalAmount = NSAttributedString(string: ", Total Amount: \(ingredientDetail.totalAmount)", attributes: boldAttributes)
                attributedText.append(totalAmount)
                content.attributedText = attributedText
            } else {
                content.text = "Name: \(ingredientDetail.ingredient.name!), Amount: \(ingredientDetail.ingredient.amount)"
            }
            cell.contentConfiguration = content
            return cell
        }
    }