My tableview currently looks like this.
and here is the code for the cellForRowAtIndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "monthlyCell", for: indexPath) as! MonthlyExpenseTableViewCell
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 64
let expense = expensePerMonth[indexPath.row]
let date = expense.modificationDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE d MMMM"
let dateString = dateFormatter.string(from: date! as Date).uppercased()
CoreDataHelper.save()
if indexPath.row == 0{
newMode = true
}
if indexPath.row>=1{
monthlyExpenses.sorted(by: { $0.modificationDate as! Date > $1.modificationDate as! Date})
let previousExpensesData = monthlyExpenses[indexPath.row - 1].modificationDate
let day = Calendar.current.component(.day, from: monthlyExpenses[indexPath.row].modificationDate as! Date) // Do not add above 'date' value here, you might get some garbage value. I know the code is redundant. You can adjust that.
let previousDay = Calendar.current.component(.day, from: monthlyExpenses[indexPath.row - 1].modificationDate! as Date)
if day == previousDay {
newMode = false
} else {
newMode = true
}
}
var expenseAmountCalculating:Double = Double(expense.amount!)!
var expenseAmountDisplayed:String = convertToMoney(expenseAmountCalculating)
var finalDisplayed:String = expense.currencySymbol! + " " + expenseAmountDisplayed
cell.dateLabel.text = dateString
cell.expenseName2.text = expense.name
cell.expenseAmount2.text = finalDisplayed
cell.expenseCategory2.text = expense.category
cell.expenseCollection2.text = expense.collection
if (expense.expense) {
cell.expenseAmount2.textColor = UIColor.red
}
else if (expense.income){
cell.expenseAmount2.textColor = UIColor(red:0.49, green:0.83, blue:0.13, alpha:1.0)
}
if (expense.cash) && (expense.expense){
cell.cashOrCredit.image = #imageLiteral(resourceName: "Cash-Expense Icon")
}
else if (expense.cash) && (expense.income){
cell.cashOrCredit.image = #imageLiteral(resourceName: "Cash-Income Icon")
}
else if (expense.credit) && (expense.income){
cell.cashOrCredit.image = #imageLiteral(resourceName: "Credit-Income Icon")
}
else if (expense.credit) && (expense.income){
cell.cashOrCredit.image = #imageLiteral(resourceName: "Credit-Expense Icon")
}
if newMode == false{
cell.dateLabel.isHidden = true
tableView.rowHeight = 64
cell.expenseName2.frame.origin = CGPoint(x: 60, y: 11)
cell.expenseCategory2.frame.origin = CGPoint(x: 61, y: 33)
cell.expenseCollection2.frame.origin = CGPoint(x: 108, y: 33)
}
else if newMode == true{
tableView.estimatedRowHeight = 64
}
return cell
}
As you can see, the expenses are grouped by date. When I delete an expense which is at the top, I want the next expense to take over and show the datelabel. This is the label at the top which shows the dates and is invisible for expenses which already exist for a certain date. However, when I delete an expense, I get a EXC_BAD_INSTRUCTION at this line:
let dateString = dateFormatter.string(from: date! as Date).uppercased()
probably because the datelabel is invisible for the cell.
So how do I go about doing this?
The code for deleting the cell is this:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let collection = monthlyExpenses[indexPath.row]
CoreDataHelper.deleteExpense(expense: collection)
monthlyExpenses.remove(at: indexPath.row )
monthlyExpenses = CoreDataHelper.retrieveExpenses()
}
}