I am trying to delete a cell in the tableview from another view controller. I have modeled my code similar to the question posted below but I still can't seem to successfully delete the selected row/cell in the CalorieVC when the delete button is pressed in the DeleteVC
Deleting a row of a tableview from another viewcontroller
SideNote: there is button in the cells to popup the DeleteVC, I am also getting an error upon pressing the the deleteBtn in the CalorieVC: DeleteRowInTableviewDelegate on let picked
saying Thread 1: Fatal error: Index out of range
import UIKit
class CalorieViewController: UIViewController {
var selectedFood: FoodList! // allows data to be passed into the CalorieVC
var deleteItems: CalorieItem? // passes data to DeleteVC
// allows data to be sepearted into sections
var calorieItems: [CalorieItem] = []
var groupedCalorieItems: [String: [CalorieItem]] = [:]
var dateSectionTitle: [String] = []
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
// Allows data in cells to seperate by section
groupedCalorieItems = Dictionary(grouping: calorieItems, by: {$0.foodList.date})
dateSectionTitle = groupedCalorieItems.map{$0.key}.sorted()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DeleteSegue" {
let vc: DeleteViewController = segue.destination as! DeleteViewController
vc.deleteItems = self.deleteItems
// vc.delegate = self
}
}
}
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 caloriesToDisplay = groupedCalorieItems[date]![indexPath.row]
calorieCell.configure(withCalorieItems: caloriesToDisplay.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, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let calorieFooter = tableView.dequeueReusableCell(withIdentifier: "CalorieFooter") as! CalorieFooter
//Cell Total Code
let date = dateSectionTitle[section]
let subtotal = groupedCalorieItems[dispensary]?.map { $0.getCalorieTotal() }.reduce(0, +) ?? 0
calorieFooter.calorieTotal.text = String(subtotal!)
return calorieFooter
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
}
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
let picked = dateSectionTitle[rowToDelete]
let selectedCell = groupedCalorieItems[dod]
delete(selectedCell)
// calorieItems.remove(at: rowToDelete) // tried using this and I get an error code upon segueing back to the CalorieVC
tableView.reloadData()
}
}
import UIKit
protocol DeleteRowInTableviewDelegate: NSObjectProtocol {
func deleteRow(inTableview rowToDelete: Int)
}
class DeleteViewController: UIViewController {
var modifyItems: CartItem!
var delegate: DeleteRowInTableviewDelegate?
@IBOutlet weak var deleteLbl: UILabel!
@IBOutlet weak var deleteBtn: UIButton!
@IBOutlet weak var cancelBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if isMovingFromParent {
delegate!.deleteRow(inTableview: 1)
}
deleteLbl.text = "Are you sure you want to delete this Food Item from your calorie List?"
}
@IBAction func decline(_ sender: Any) {
dismiss(animated: true)
delegate!.deleteRow(inTableview: 1)
print("Delete Item")
}
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
print("Cancel Delete")
}
}
Remove the table cell
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
if caloriesItems.count > rowToDelete {
calorieItems.remove(at: rowToDelete)
tableView.deleteRows(at: [IndexPath(row: rowToDelete, section: 0)], with: .automatic)
} else {
print("index not present")
}
}
}
Do not call reloadData just to delete one row. This is a bad practice. Use deleteRows instead.