Я создаю приложение todo plan, и я столкнулся с серьезной ошибкой в моем tableViewCell.Всякий раз, когда я выбираю строку более одного раза, в строке вызывается неправильный indexPath.
Если я закомментирую свой resultsController.delegate
, приложение будет работать нормально.Однако мне нужен делегат контроллера результатов, чтобы обновлять представление таблицы каждый раз, когда создается новый план.
override func viewDidLoad() {
super.viewDidLoad()
// Create Request
let request:NSFetchRequest<Plan> = Plan.fetchRequest()
let sortDescriptors = NSSortDescriptor(key: "date", ascending: true) // make request more specific
request.sortDescriptors = [sortDescriptors]
// Init our results controller
resultsController = NSFetchedResultsController(
fetchRequest: request,
managedObjectContext: coreDataStack.managedContext,
sectionNameKeyPath: nil,
cacheName: nil
)
resultsController.delegate = self
// Perform fetch request
do {
try resultsController.performFetch()
} catch {
print("Perform fetch error \(error)")
}
}
Вот соответствующие TableViewDelegates
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showNewPlan", sender: tableView.cellForRow(at: indexPath))
}
Также я добавил свою функцию подготовки к навигации.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let _ = sender as? UIBarButtonItem , let vc = segue.destination as? NewPlanViewController {
vc.managedContext = resultsController.managedObjectContext
}
if let cell = sender as? UITableViewCell , let vc = segue.destination as? NewPlanViewController {
vc.managedContext = resultsController.managedObjectContext
if let indexPath = tableView.indexPath(for: cell) {
let plan = resultsController.object(at: indexPath)
vc.plan = plan
}
}
}
resultsControllerDelegate
- это то, как я обновляю tableViewCells
.
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: .automatic)
}
case .delete:
if let indexPath = indexPath {
tableView.deleteRows(at: [indexPath], with: .automatic)
}
case .update:
if let indexPath = indexPath, let cell = tableView.cellForRow(at: indexPath) {
let plan = resultsController.object(at: indexPath)
cell.textLabel?.text = plan.title
}
default:
break
}
}