更新无效:UITableView中的节数无效

我找不到所遇到问题的答案。我正在使用NSFetchedResultsControllerDelegete将表视图与数据连接起来。我正在获取具有sectionNameKeyPath设置的数据,以便可以在表视图中对项目进行分组。如果我在表视图的一部分中只有一个项目并将其删除,则会收到以下错误:

  

无效的更新:无效的节数。更新(1)之后在表格视图中包含的节数必须等于更新(2)之前在表格视图中包含的节数,加上或减去插入或删除的节数(已插入0、0删除)。

这是删除之前我的屏幕:

更新无效:UITableView中的节数无效

这是该视图的代码:

import CoreData

class VehicletableViewController: UITableViewController,NSFetchedResultsControllerDelegate {

    var deleteItemIndexPath: IndexPath? = nil

    lazy var dao: DAOUtilities = {
        return DAOUtilities(context: GlobalVariables.getcontext())
    }()

    lazy var fetchedResultsController: NSFetchedResultsController<Vehicles> = {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Vehicles")

        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "activeflag",ascending: false),NSSortDescriptor(key: "vehicleDesc",ascending: true)]

        // Initialize Fetched Results Controller
        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,managedobjectcontext: GlobalVariables.getcontext(),sectionNameKeyPath: "activeflag",cacheName: nil)

        // Configure Fetched Results Controller
        fetchedResultsController.delegate = self

        return fetchedResultsController as! NSFetchedResultsController<Vehicles>
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

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

        do {
            try self.fetchedResultsController.performFetch()
        }
        catch {
            let fetchError = error as NSError
            print("\(fetchError),\(fetchError.userInfo)")
        }
        tableView.reloadData()
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        if let sections = fetchedResultsController.sections {
            return sections.count
        }

        return 0
    }

    override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        if let sections = fetchedResultsController.sections {
            let sectionInfo = sections[section]
            return sectionInfo.numberOfObjects
        }

        return 0
    }

    override func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView()
        view.backgroundColor = UIColor(red: 55/255,green: 120/255,blue: 250/255,alpha: 1)

        guard let sectionInfo = fetchedResultsController.sections?[section] else {
            return view
        }
        let title = UILabel()
        title.font = UIFont.boldSystemFont(ofSize: 16)
        title.textColor = .white
        title.text = sectionInfo.name == "1" ? "active" : "Inactive"
        view.addSubview(title)
        title.translatesAutoresizingMaskintoConstraints = false
        title.centerYAnchor.constraint(equalTo: view.centerYAnchor).isactive = true
        title.leftAnchor.constraint(equalTo: view.leftAnchor,constant: 16).isactive = true

        return view
    }

    override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "vehicleCell",for: indexPath)

        if indexPath.row % 2 == 0 {
            cell.backgroundColor = UIColor.clear
        }
        else {
            cell.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
        }

        let vehicle = fetchedResultsController.object(at: indexPath)
        cell.textLabel!.text = vehicle.vehicleDesc

        return cell
    }

    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView,canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView,commit editingStyle: UITableViewCell.EditingStyle,forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            deleteItemIndexPath = indexPath
            let vehicle = fetchedResultsController.object(at: indexPath)
            confirmDelete(itemToDelete: vehicle.vehicleDesc!)
        }
    }

    func confirmDelete(itemToDelete: String) {
        let alert = UIAlertController(title: "Delete Vehicle",message: "Are you sure you want to delete vehicle \(itemToDelete)",preferredStyle: .actionSheet)
        let deleteaction = UIAlertaction(title: "Delete",style: .destructive,handler: handleDeleteItem)
        let cancelaction = UIAlertaction(title: "Cancel",style: .cancel,handler: cancelDeleteItem)
        alert.addaction(deleteaction)
        alert.addaction(cancelaction)
        self.present(alert,animated: true,completion: nil)
    }

    func handleDeleteItem(alertaction: UIAlertaction!) -> Void {
        if let indexPath = deleteItemIndexPath {
            let vehicle = fetchedResultsController.object(at: indexPath)
            let route = dao.getRouteForVehicle(vehicleId: vehicle.vehicleId!)

            if let _ = route {
                vehicle.activeflag = false
            }
            else {
                GlobalVariables.getcontext().delete(vehicle)
            }
        }
    }

    func cancelDeleteItem(alertaction: UIAlertaction!) {
        deleteItemIndexPath = nil
    }

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,didChange anObject: Any,at indexPath: IndexPath?,for type: NSFetchedResultsChangeType,newIndexPath: IndexPath?) {
        switch (type) {
        case .insert:
            if let indexPath = newIndexPath {
                tableView.insertRows(at: [indexPath],with: .fade)
            }
            break;
        case .delete:
            if let indexPath = indexPath {
                tableView.deleteRows(at: [indexPath],with: .fade)
                tableView.reloadData()
            }
            break;
//        case .update:
//            if let indexPath = indexPath {
//                let cell = tableView.cellForRow(at: indexPath)
//                configureCell(cell,atIndexPath: indexPath)
//            }
//            break;
        case .move:
            if let indexPath = indexPath {
                tableView.deleteRows(at: [indexPath],with: .fade)
            }

            if let newIndexPath = newIndexPath {
                tableView.insertRows(at: [newIndexPath],with: .fade)
            }
            break;
        default:
            break
        }
    }

    // MARK: - segue

    override func prepare(for segue: uistoryboardSegue,sender: Any?) {
        if segue.identifier == "editVehicleSegue" {
            if let vehicleEditViewController = segue.destination as? VehicleEditViewController {
                if let indexPath = tableView.indexPathForSelectedRow {
                    let vehicle = fetchedResultsController.object(at: indexPath)
                    vehicleEditViewController.vehicle = vehicle
                    vehicleEditViewController.tableView = tableView
                }
            }
        }
    }

//    // MARK: - actions
//
//    @IBaction func btnAdd_actION(_ sender: UIBarButtonItem) {
//        var emptyFound = false
//        for i in 0..<vehicles.count {
//            let vehicle = vehicles[i]
//            if vehicle.isEmpty {
//                emptyFound = true
//                break
//            }
//        }
//        if !emptyFound {
//            vehicles.append("")
//            tableView.reloadData()
//        }
//    }
}
ychzd_ok 回答:更新无效:UITableView中的节数无效

从某个部分中删除最后一行时,您需要让表格查看整个部分已被删除。

您可以通过实施

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,didChange sectionInfo: NSFetchedResultsSectionInfo,atSectionIndex sectionIndex: Int,for type: NSFetchedResultsChangeType) {

    let section = IndexSet(integer: sectionIndex)

    switch type {
        case .delete:
            tableView.deleteSections(section,with: .automatic)
        case .insert:
            tableView.insertSections(section,with: .automatic)
    }
}
本文链接:https://www.f2er.com/3140725.html

大家都在问