如何在 Swift 中获取表格视图单元格数据的总和?

Posted

技术标签:

【中文标题】如何在 Swift 中获取表格视图单元格数据的总和?【英文标题】:How can I take the sum of table view cells' data in Swift? 【发布时间】:2020-04-20 04:46:27 【问题描述】:

我正在尝试将所有金额数据相加并发送到不同的表格视图单元格。我想我需要先将 String 转换为 Double 才能执行此操作,但我也不确定如何执行此操作。有谁知道如何获取数据总和并将其呈现在其他地方?我对 swift 很陌生,无法弄清楚我需要在哪里编写这段代码。

import Foundation

struct Income: Codable 
    var name: String
    var amount: String

    init(name: String, amount: String) 
        self.name = name
        self.amount = amount
    


    static let DocumentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

    static let ArchiveURL = DocumentsDirectory.appendingPathComponent("incomes").appendingPathExtension("plist")

    static func loadSampleIncomes() -> [Income] 
        return [
            Income(name: "Main Income", amount: "0"),
            Income(name: "Secondary Income", amount: "0"),
            Income(name: "Interest Income", amount: "0")]

    

    static func saveToFile(incomes: [Income]) 
           let propertyListEncoder = PropertyListEncoder()
           let codedIncomes = try? propertyListEncoder.encode(incomes)

           try? codedIncomes?.write(to: ArchiveURL, options: .noFileProtection)

    

    static func loadFromFile() -> [Income]? 
            guard let codedIncomes = try? Data(contentsOf: ArchiveURL) else  return nil 

            let propertyListDecoder = PropertyListDecoder()

            return try? propertyListDecoder.decode(Array<Income>.self, from: codedIncomes)
    




import UIKit

class IncomeTableViewController: UITableViewController 

var incomes: [Income] = []


override func viewDidLoad() 
    super.viewDidLoad()

    tableView.tableFooterView = UIView(frame: CGRect.zero)

if let savedIncomes = Income.loadFromFile() 
        incomes = savedIncomes
     else 
        incomes = Income.loadSampleIncomes()
    



override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    tableView.reloadData()


// table view data source

override func numberOfSections(in tableView: UITableView) -> Int 
     return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
       if section == 0 
           return incomes.count
        else 
           return 0
       


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: "incomeCell", for: indexPath) as! IncomeTableViewCell

    let income = incomes[indexPath.row]

    cell.update(with: income)
    cell.showsReorderControl = true

    return cell





// MARK: - Table view delegate

override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle 
    return .delete



override func tableView(_ tableView: UITableView, commit
    editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath:
    IndexPath) 
        if editingStyle == .delete 
            incomes.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: . automatic)
            Income.saveToFile(incomes: incomes)
       


override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) 
      let movedIncome = incomes.remove(at: fromIndexPath.row)
      incomes.insert(movedIncome, at: to.row)
      tableView.reloadData()



@IBAction func editButtonTapped(_ sender: UIBarButtonItem) 
    let tableViewEditingMode = tableView.isEditing

    tableView.setEditing(!tableViewEditingMode, animated: true)


// Navigation

@IBAction func unwindToIncomeTableView(segue:UIStoryboardSegue) 
    guard segue.identifier == "saveIncomeUnwind",
    let sourceViewController = segue.source as? AddEditIncomeTableViewController,

    let income = sourceViewController.income else  return 
        if let selectedIndexPath = tableView.indexPathForSelectedRow 
            incomes[selectedIndexPath.row] = income
            tableView.reloadRows(at: [selectedIndexPath],
            with: .none)
         else 
            let newIndexPath = IndexPath(row: incomes.count, section: 0)
            incomes.append(income)
            tableView.insertRows(at: [newIndexPath], with: .automatic)
        

        Income.saveToFile(incomes: incomes)


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "EditIncome" 
        let indexPath = tableView.indexPathForSelectedRow!
        let income = incomes[indexPath.row]
        let navController = segue.destination as! UINavigationController
        let addEditIncomeTableViewController = navController.topViewController as! AddEditIncomeTableViewController

        addEditIncomeTableViewController.income = income
    




import UIKit

class AddEditIncomeTableViewController: UITableViewController 

    @IBOutlet weak var saveButton: UIBarButtonItem!
    @IBOutlet weak var incomeNameTextField: UITextField!
    @IBOutlet weak var incomeAmountTextField: UITextField!

    var income: Income?

    override func viewDidLoad() 
        super.viewDidLoad()

        if let income = income 
            incomeNameTextField.text = income.name
            incomeAmountTextField.text = income.amount


        

        updateSaveButtonState()
    



    override func prepare(for segue: UIStoryboardSegue, sender:
      Any?) 
          super.prepare(for: segue, sender: sender)

          guard segue.identifier == "saveIncomeUnwind" else  return 

          let name = incomeNameTextField.text ?? ""
          let amount = incomeAmountTextField.text ?? ""
          income = Income(name: name, amount: amount)
    

    func updateSaveButtonState() 
            let nameText = incomeNameTextField.text ?? ""
            let amountText = incomeAmountTextField.text ?? ""
            saveButton.isEnabled = !nameText.isEmpty && !amountText.isEmpty
        

    @IBAction func textEditingChanged(_ sender: UITextField) 
    updateSaveButtonState()


    



这是我希望在其中显示新数据的表格视图控制器。

    import UIKit

    class BudgetHomeTableViewController: UITableViewController 

    var incomes: [Income] = []
    var expenses: [Expense] = []

    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.tableFooterView = UIView(frame: CGRect.zero)

        if let savedIncomes = Income.loadFromFile() 
            incomes = savedIncomes
         else 
            incomes = Income.loadSampleIncomes()
        

        if let savedExpenses = Expense.loadFromFile() 
            expenses = savedExpenses
         else 
            expenses = Expense.loadSampleExpenses()
         
    
    


这是专门显示数据的单元格

    import UIKit

    class BugetBalanceCell: UITableViewCell 

    @IBOutlet weak var budgetBalanceText: UILabel!

    var incomes: [Income] = []
    var expenses: [Expense] = []




    override func awakeFromNib() 
        super.awakeFromNib()

     let incomeTotal = incomes.map(Double($0.amount) ?? 0).reduce(0, +)
     let expenseTotal = expenses.map(Double($0.amount) ?? 0).reduce(0, +)

     let balance = incomeTotal - expenseTotal


    




    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    
    

【问题讨论】:

你想在哪里显示收入的总和? @DilanAnuruddha 我想在不同的新表格视图控制器单元格上显示它。我基本上拥有所有这些代码,但也有费用。我想取每个的总和,并在两者之间取得平衡。收入 - 费用。 在这段代码中只有收入。你如何得到费用? @DilanAnuruddhaI 有 ExpenseTableViewController、AddEditExpensesTableViewController 等。我的收入代码和表格视图与费用完全相同。我没有显示费用代码。如果我创建了一个新的 TableViewController,我将如何在其中显示余额? 你可以在下一个 tableview 控制器中使用我的答案来显示平衡 【参考方案1】:

首先定义你的收入、支出数组并加载数据

var incomes: [Income] = []
var expenses: [Income] = []


if let savedIncomes = Income.loadFromFile() 
    incomes = savedIncomes
 else 
    incomes = Income.loadSampleIncomes()


//do the same thing for load data to expenses array

你可以得到你的余额 = 收入 - 支出使用

let incomeTotal = incomes.map(Double($0.amount) ?? 0).reduce(0, +)
let expenseTotal = expenses.map(Double($0.amount) ?? 0).reduce(0, +)

let balance = incomeTotal - expenseTotal

在下一个表格视图控制器中您想显示的位置使用此值

【讨论】:

我不确定自己做错了什么,但我收到错误消息“使用未解析的标识符‘收入’”和“使用未解析的标识符‘费用’” 你需要在 next tableviewcontroller 中定义这两个数组,并先将数据加载到数组中 我已将顶部部分实现到我的新 tableview 控制器中。我是否将底部放在 tableview 单元格中? “使用未解析的标识符'收入',使用未解析的标识符'费用'”当我放入表格视图单元格时。我一定是做错了什么,但还是感谢您的帮助! 我需要将它连接到 UILabel!【参考方案2】:
(income as NSArray).valueForKeyPath("@sum.self")

【讨论】:

我在哪里放这个 最好在 Swift 数组上使用 reduce 函数。将 Swift 数组转换为 NSArray 并不是免费的。

以上是关于如何在 Swift 中获取表格视图单元格数据的总和?的主要内容,如果未能解决你的问题,请参考以下文章

从 Swift (3.1) 表格视图中动态创建的单元格获取有序的文本字段数据

如何使用 Swift 在集合视图单元格中添加表视图?

如何根据步进值而不是 swift 3 中单元格的物理选择来选择表格视图的单元格?

防止在表格视图Swift中重用自定义单元格

如何在 swift 4 中的另一个表视图控制器中获取该表视图单元格中的文本字段文本?

如何在单元格 Swift 2 中删除项目后重新加载表格视图