Reputation: 33
I'm trying to add up all of the amount data and send to a different table view cell. I think I need to convert String to Double before I can do this, but I'm not sure how to do this either. Does anyone know how you can take the sum of data and present it somewhere else? I'm very new to swift and am having trouble figuring out where I need to write this code.
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()
}
}
this is the table view controller in which I want the new data to be presented.
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()
}
}
}
This is the cell where the data will be presented specifically
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
}
}
Upvotes: 0
Views: 761
Reputation: 2698
First define your income,expenses arrays and load data
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
you can get your balance = incomes - expenses using
let incomeTotal = incomes.map({Double($0.amount) ?? 0}).reduce(0, +)
let expenseTotal = expenses.map({Double($0.amount) ?? 0}).reduce(0, +)
let balance = incomeTotal - expenseTotal
use this value where you want to show in next Table View conntroller
Upvotes: 1