更改数据和popViewController之后,TableView不会重新加载

时间:2019-09-08 15:19:37

标签: swift uitableview delegates nsfetchedresultscontroller

在我的应用程序中,添加新数据后,我使用NSFetchedResultsControllerDelegate重新加载Tableview,但是此解决方案仅在我第一次访问视图时有效。

如果我删除数据并再次添加,则信息不会显示在表格视图中。为此,我需要离开视图并再次访问它。

我尝试使用Delegates和CallBack重新加载表格视图,但未成功。

我发现删除旧数据后立即添加新数据后,不会调用cellForRowAt。尽管已经调用了numberOfSections。

我迷路了。有人可以帮我吗?

Here is the video with app behaviour

在这里,我向您展示部分代码:

我的NSFetchedResultsControllerDelegate

extension MeasureController: NSFetchedResultsControllerDelegate {

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        myTableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
    case .delete:
        myTableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
    case .move:
        break
    case .update:
        myTableView.reloadSections(IndexSet(integer: sectionIndex), with: .fade)
    @unknown default:
        fatalError()
    }
}


func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    myTableView.reloadData()
    myCollectionView.reloadData()
}

//Allow to show full section name in header.
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, sectionIndexTitleForSectionName sectionName: String) -> String? {
    return sectionName
}

}

viewWillAppear出现在具有表视图的MeasureController中

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

    self.fillDataInTheView()
    self.allMeasures = CoreDataManager.shared.loadAllMeasuresByAthlete(athlete: athleteToShow)

    //Get the last recorded date that has measures records
    if let allMeasures = self.allMeasures, let selectedDay = CoreDataManager.shared.getLastDayWithMeasures(measure: allMeasures) {
        self.selectedDay = selectedDay
    }

    if selectedDay != nil {
        if let measureByAthleteAndDay = CoreDataManager.shared.loadAllMeasuresByAthleteAndDay(athlete: athleteToShow, day: selectedDay) {
            self.measureByAthleteAndDay = measureByAthleteAndDay
        }

        do {
            try fetchedRCAllMeasuresByDay.performFetch()
        } catch let fetchedError {
            print("Error fetching Measures by Day:", fetchedError)
        }
    }

    do {
        try fetchedRCDay.performFetch()
    } catch let err {
        print(err)
    }

    if let lastEvaluation = getRecentDate() {
        lbEvaluationDate.text = "Última Avaliação: \(lastEvaluation.mediumDate())"
    } else {
        lbEvaluationDate.text = "Sem Avaliação Registrada"
    }

    self.myTableView.reloadData()
}

这是我的myCollectioView,用于显示日期数据

extension MeasureController: UICollectionViewDelegate, UICollectionViewDataSource {

// MARK: - Collection View Data Source

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    guard let dates = fetchedRCDay.fetchedObjects else {return 0}
    return dates.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: cellCollectionViewID, for: indexPath) as! DateCollectionCell
    let day = fetchedRCDay.object(at: indexPath)
    if let date = day.title {
        cell.setupCell(date: date)
    }

    if day == selectedDay {
        cell.isSelected = true
    } else {
        cell.isSelected = false
    }

    cell.delegate = self

    return cell
}

// MARK: - Collection View Delegate

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    self.selectedCell(true, indexPath: indexPath)
    let day = fetchedRCDay.object(at: indexPath)
    self.alertToCreateEvaluation(day: day)
    myCollectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    self.selectedCell(false, indexPath: indexPath)
    let day = fetchedRCDay.object(at: indexPath)
    if let date = day.title {
        lbEvaluationDate.text = "Data da Avaliação: \(date.mediumDate())"
    }
}

func hasMeasures(cell: DateCollectionCell, day: Day) {

    if day.allMeasures == nil {
        cell.ivIndicator.isHidden = true
    } else {
        cell.ivIndicator.isHidden = false
    }
}

}

如果您需要更多代码来更好地理解它,请告诉我。

1 个答案:

答案 0 :(得分:0)

按照Apple文档NSFetchedResultControllerDelegate尝试......

添加新的实例方法:

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

    tableView.beginUpdates()
}

更改现有的controllerDidChangeContent(_:)实例方法:

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

    tableView.endUpdates()
}

省去对.reloadData()的调用-这些是“蛮力”便利方法,可重新加载整个表或集合视图,并使微妙的FRC Delegate方法的使用变得多余。