如何通过页脚单元格在表视图中使用委托?

How to pass using delegates in a tableview through the footer cell?

我想做的是通过 CalorieFooter 单元格中的按钮将数据传递到另一个视图控制器,使用委托在单元格中传递数据。

我无法通过 CalorieFooter 单元格中的信息按钮成功传递数据,无法在 CalorieBreakdownController 中显示当天卡路里消耗的脂肪、碳水化合物和蛋白质。

我目前在 CalorieBreakdownController 的所有标签中都得到“0”(如图中最右侧所示)。

我认为问题可能是因为我的 calculationDelegate 是在 CalorieFooter 单元格中完成的。我在单元格中得到小计的方法是将单元格分成几个部分。我对如何将数据从页脚传递到 CalorieBreakdownController 以获取标签中的 "Subtotal" 感到有点困惑。

我如何才能将 "subTotal" 数据从 calorieFooter 单元格传递给 CalorieBreakdownController(如下图所示)

在此先感谢您提供的任何帮助

 import UIKit

 class CalorieViewController: UIViewController {

    var selectedFood: FoodList!
    var additionalCalories: DailyCalories!                  // delegate code for footer

    var calorieItems: [DailyCalories] = []
    var groupedCalorieItems: [String: [DailyCalories]] = [:]
    var dateSectionTitle: [DailyCalories] = []

    @IBOutlet weak var calorieTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        groupedFoodItems = Dictionary(grouping: calorieItems, by: {[=10=].foodList.day})
        dateSectionTitle = groupedCalorieItems.map{[=10=].key}.sorted()

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         if let vc = segue.destination as? CalorieTotalController {   // delegate code for footer
            vc.additionalCalories = self.additionalCalories
        }
    }
}

extension CalorieViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return dateSectionTitle.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let date = dateSectionTitle[section]
        return groupedCalorieItems[date]!.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let calorieCell = tableView.dequeueReusableCell(withIdentifier: "CalorieCell") as! CalorieCell

        let date = dateSectionTitle[indexPath.section]
        let calorieItemsToDisplay = groupedCalorieItems[date]![indexPath.row]
        calorieCell.configure(withCartItems: calorieItemsToDisplay.foodList)

        return calorieCell
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let calorieHeader = tableView.dequeueReusableCell(withIdentifier: "CalorieHeader") as! CalorieHeader

        let headerTitle = dateSectionTitle[section]
        calorieHeader.dateLbl.text = "Date: \(headerTitle)"

        return calorieHeader
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let calorieFooter = tableView.dequeueReusableCell(withIdentifier: "CalorieFooter") as! CalorieFooter

        let date = dateSectionTitle[section]
        let arrAllItems = groupedCalorieItems[dispensary]!
        var subtotal: Float = 0
        for item in arrAllItems {
            if item.foodList.selectedOption == 1 {
                 subtotal = subtotal + (Float(item.foodList.calorie1) * Float(item.foodList.count))
            } else if item.foodList.selectedOption == 2 {
                 subtotal = subtotal + (Float(item.foodList.calorie2) * Float(item.foodList.count))
            } else if item.foodList.selectedOption == 3 {
                 subtotal = subtotal + (Float(item.foodList.calorie3) * Float(item.foodList.count))
            }
        }

        calorieFooter.cartTotal.text = "\(subtotal)"
        calorieFooter.calculationDelegate = self                  // delegate code for footer
        calorieFooter.additionalCalories! = ???                   // can't get the right code set to allow the data to pass
        calorieFooter.calculations! = ???                         // can't get the right code set to allow the data to pass
        return calorieFooter
    }  
}

extension CalorieViewController: CalculationDelegate {     // delegate code for footer
    func onTouchInfoButton(from cell: CalorieFooter) {
        self.additionalCalories = cell.additionalCalories
        self.performSegue(withIdentifier: "CalculateDailyCalorieCell", sender: self)
    }
}

import UIKit

protocol CalculationDelegate: class {                     // delegate code for footer
    func onTouchInfoButton(from cell: CalorieFooter)
}

class CalorieFooter: UITableViewCell {

    weak var calculationDelegate: CalculationDelegate?   // delegate code for footer
    var additionalCalories: DailyCalories!                            // delegate code for footer
    var calculations: [DailyCalories] = []

    @IBOutlet weak var calorieTotal: UILabel!

    @IBOutlet weak var additionalFeesBtn: UIButton!


    @IBAction func overallTotalBtn(_ sender: Any) {
         self.additionalFeesDelegate?.onTouchInfoButton(from: self)   // delegate code for footer
    }
}

class CalorieTotalController: UIViewController {

    var additionalCalories: DailyCalories!             // delegate code for footer
    var calculations: [DailyCalories] = []            // delegate code for footer

    @IBOutlet weak var calorieSubtotal: UILabel!

    @IBOutlet weak var fatTotal: UILabel!
    @IBOutlet weak var carbTotal: UILabel!
    @IBOutlet weak var proteinTotal: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // calculations done for when data is passed through Delegate
        var subtotal: Float = 0
        for item in calculations {
            if item.foodList.selectedOption == 1 {
                 subtotal = subtotal + (Float(item.foodList.calorie1) * Float(item.foodList.count))
            } else if item.foodList.selectedOption == 2 {
                 subtotal = subtotal + (Float(item.productList.calorie2) * Float(item.foodList.count))
            } else if item.foodList.selectedOption == 3 {
                 subtotal = subtotal + (Float(item.foodList.calorie3) * Float(item.foodList.count))
            }
        }

        let protein = Float(subtotal * 0.25)
        let carbs = Float(subtotal * 0.25)
        let fat = Float(subtotal * 0.5)

        calorieSubtotal.text = String(subtotal!)
        proteinTotal.text = String(protein!)
        fatTotal.text = String(fat!)
        carbTotal.text = String(carbs!)

    }

    @IBAction func closeButton(_ sender: Any) {
        dismiss(animated: true, completion: nil)
        print("Calories BreakDown")
    }    
}

我想,在 viewForFooterInSection() 函数中,您忘记为 calorieFooter.additionalCalories !

设置任何值

calorieFooter.additionalCalories 应该是 DailyCalories 类型而不是 DailyCalories 数组。

例如你可以设置-

let date = dateSectionTitle[section]
calorieFooter.additionalCalories = date

没有“!”签名,每当你为任何变量赋值时,你 不需要使用 !最后.

使用委托可能是个好主意。我只是写了一些代码(未经测试!)让您了解它是如何工作的:

延长委托 class:

protocol CalculationDelegate: class {
    func onTouchInfoButton(from cell: CalorieFooter)
    func getAdditionalCalories() -> Int
    func getCalculations() -> Int // or whatever type this object should be
}

确保您的视图控制器遵循协议:

extension CalorieViewController: CalculationDelegate { 
    func onTouchInfoButton(from cell: CalorieFooter) { ... }
    func getAdditionalCalories() -> Int {
        return self.calories
    }
    func getCalculations() -> Int {
        return self.calculations
    }
}

将局部变量添加到存储当前状态的 CalorieViewController(calories/calculations 的数量)

class CalorieViewController: UIViewController {
    private var calories: Int = 0
    private var calculations: Int = 0

    ... other code that is already in the UIViewController
}

确保在某处初始化这些变量!类似于:

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    ... same as before...

    self.calories = subtotal // I guess?
    self.calculations = calculations // put this somewhere where calculations is initialized
}

现在,数据应该在CalorieFooter中可用。当 calculationDelegate 为 nil:

时,我添加了默认值 0
let calories = calculationDelegate?.getAdditionalCalories() ?? 0
let calculations = calculationDelegate?.getCalculations() ?? 0

祝你好运!