Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

number of rows contained in existing section after update (15) must equal

So i'm building an app as a hobby and have researched, it appears a few people have a similar problem, except mine happens when inserting the data to begin with. So I think it's slightly different.

When I go to insert data into my array and table it returns an error (title), it retrieves the right amount of current count, but struggled to add a new one.

class AccountsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var totalLabel: UILabel!
    @IBOutlet weak var tableview: UITableView!
    @IBOutlet weak var tableview2: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //Set the table background as the image
        tableview.backgroundView = UIImageView(image: UIImage(named: "splasnowords-1.png"))

        //Use the edit button item provided by the table view controller
        navigationItem.leftBarButtonItem = editButtonItem
        //self.navigationItem.leftBarButtonItem = self.editButtonItem;

        //Calculate the latest totalstandings
        BudgetDataModel.calculateTotalStandings()
        totalLabel.text = ("Total Current Standings = £\(BudgetDataModel.returnTrueValue(number: BudgetDataModel.total))")

        self.tableview.delegate = self
        self.tableview2.delegate = self
        self.tableview.dataSource = self
        self.tableview2.dataSource = self
    }

    // MARK: - Table view data source
    func numberOfSections(in tableView: UITableView) -> Int {
        if (tableView == tableview){
        return 1
            //BudgetDataModel.budgets.count
        }
        else{
            return 2
                //SavingsDataModel.savings.count
        }
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
        //reload data?
        if (tableView == tableview){
            return "Budgets"
        }
        else{
            return "Savings"
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        var rowCount = 0
        if (tableView == self.tableview) {
            rowCount = BudgetDataModel.budgets.count
        }
        if (tableView == self.tableview2) {
            rowCount = SavingsDataModel.savings.count
        }
        return rowCount

        // #warning Incomplete implementation, return the number of rows
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       //Table view cells are reused and should be dequeued using a cell identifier.
        if (tableView == self.tableview){
            let cellIdentifier = "AccountsTableViewCell"
            let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! AccountsTableViewCell

            let budget = BudgetDataModel.budgets[(indexPath as NSIndexPath).row]

            cell.nameLabel.text = budget.name
            cell.amountLabel.text = ("£\(BudgetDataModel.returnTrueValue(number: budget.amount))")
            cell.backgroundColor = UIColor(white: 1, alpha: 0.5)
            return cell
        }
        else if (tableView == self.tableview2){
            let cellIdentifier = "SavingsTableViewCell"
            let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! SavingsTableViewCell
            let saving = SavingsDataModel.savings[(indexPath as NSIndexPath).row]

            cell.savingsnameLabel.text = saving.savingname
            cell.savingsamountLabel.text = ("£\(BudgetDataModel.returnTrueValue(number: saving.savingamount))")
            cell.backgroundColor = UIColor(white: 1, alpha: 0.5)
            return cell
         }
        else { preconditionFailure ("unexpected cell type") }
    }

    // Override to support conditional editing of the table view.
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }

    // Override to support editing the table view.
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            if (tableView == tableview){
                // Delete the row from the data source
                BudgetDataModel.budgets.remove(at: indexPath.row)
                BudgetDataModel.saveBudgets()
                BudgetDataModel.calculateTotalStandings()
                totalLabel.text = ("Total Current Standings = £\(BudgetDataModel.returnTrueValue(number:BudgetDataModel.total))")
               // self.tableview.reloadData()
                tableView.deleteRows(at: [indexPath], with: .fade)

            }
            else if (tableView == tableview2){
                // Delete the row from the data source
                SavingsDataModel.savings.remove(at: indexPath.row)
                SavingsDataModel.saveSavings()
                //implement   BudgetDataModel.calculateTotalStandings()
                //implement   totalLabel.text = ("Total Current Standings = £\(BudgetDataModel.returnTrueValue(number:BudgetDataModel.total))")
                //self.tableview2.reloadData()
                tableView.deleteRows(at: [indexPath], with: .fade)

            }
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }

    // Override to support rearranging the table view.
    func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
    }

    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowDetail"{
            let budgetDetailViewController = segue.destination as! BudgetViewController
            //Get the cell that generated this segue.
            if let selectedBudgetCell = sender as? AccountsTableViewCell {
                let indexPath = tableview.indexPath(for: selectedBudgetCell)!
                let selectedBudget = BudgetDataModel.budgets[indexPath.row]
                budgetDetailViewController.budget = selectedBudget
            }
        }
        else if segue.identifier == "AddItem"{
            //self.tableview.reloadData()
            print("Adding new budget.")
        }
        else if segue.identifier == "ShowSavings"{
                let savingDetailViewController = segue.destination as! SavingsViewController
                //Get the cell that generated this segue.
                if let selectedSavingsCell = sender as? SavingsTableViewCell {
                    let indexPath = tableview2.indexPath(for: selectedSavingsCell)!
                    let selectedSavings = SavingsDataModel.savings[indexPath.row]
                    savingDetailViewController.saving = selectedSavings
                }
        }
        else if segue.identifier == "AddSaving"{
            //self.tableview2.reloadData()
            print ("Adding new saving.")
        }
    }

    //MARK: Actions

    @IBAction func unwindToBudgetList(_ sender: UIStoryboardSegue){
        if let sourceViewController = sender.source as? BudgetViewController, let budget = sourceViewController.budget {
            if let selectedIndexPath = tableview.indexPathForSelectedRow{
                //Update an existing budget.
                BudgetDataModel.budgets[selectedIndexPath.row] = budget
                tableview.reloadRows(at: [selectedIndexPath], with: .none)
            }
            else{
                    //Add a new budget
                    let newIndexPath = IndexPath(row:BudgetDataModel.budgets.count, section: 0)
                    BudgetDataModel.budgets.append(budget)
                    tableview.insertRows(at: [newIndexPath as IndexPath], with: .bottom)
                }
            //Save the budgets.
            BudgetDataModel.saveBudgets()
            BudgetDataModel.calculateTotalStandings()
            totalLabel.text = ("Total Current Standings = £\(BudgetDataModel.returnTrueValue(number: BudgetDataModel.total))")

        }
    }

    @IBAction func unwindtoSavingsList(_ sender: UIStoryboardSegue){
        if let sourceViewController = sender.source as? SavingsViewController, let savings = sourceViewController.saving {
            if let selectedIndexPath = tableview2.indexPathForSelectedRow{
                //Update an existing budget.
                SavingsDataModel.savings[selectedIndexPath.row] = savings
                tableview2.reloadRows(at: [selectedIndexPath], with: .none)
            }
            else{
                //Add a new saving
                let newIndexPath = IndexPath(row:SavingsDataModel.savings.count, section: 1)
                SavingsDataModel.savings.append(savings)
                //tableview2.reloadData()
                tableview2.insertRows(at: [newIndexPath as IndexPath], with: .bottom)
            }
            //Save the budgets.
            SavingsDataModel.saveSavings()
            //implement    SavingsDataModel.calculateTotalStandings()
            //    totalLabel.text = ("Total Current Standings = £\(BudgetDataModel.returnTrueValue(number: BudgetDataModel.total))")

        }
    }
}
like image 801
Ben Vickers Avatar asked Oct 29 '22 10:10

Ben Vickers


1 Answers

Thanks @jcaron

Two corrections required:

  1. Change my numberofsectionscode to return 1, so that my second table didn't have a randomly replicated second section

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

  1. Replace the section with 0, when adding a new saving

//Add a new saving let newIndexPath = IndexPath(row:SavingsDataModel.savings.count, section: 1)

like image 178
Ben Vickers Avatar answered Nov 17 '22 22:11

Ben Vickers