Afonso
Afonso

Reputation: 87

Why TableView does not reload data after popViewController?

In my app I have a ViewController with a collectionView and a tableView. My CollectionView shows the dates and the tableView shows the data in that date.

I need to create a date before create the other datas, so when I type in the date it shows up a alert and them we go to other view to Create a new data.

The problem is that when I save a new data and I use a popViewController to go back my previous view my tableView does not reload data.

I can see the saved data when I back the view again and so I return to the view

I've tried to use the myTableView.reloadData() in ViewWillAppear, but it didn't work.

How can I reload myTableView as soon as return the view?

Here is a link to the app video. Here is the app working

Here is my IBAction to save data:

@IBAction func btSaveNewMeasures(_ sender: UIBarButtonItem) {

    let allMeasures = NSEntityDescription.entity(forEntityName: "AllMeasures", in: context)

    for textField in tfMeasuresValues {

        let newMeasure = NSManagedObject(entity: allMeasures!, insertInto: context)

        if let valueTxt = textField.text {
            let value = convertNumber.convertToDouble(valueTxt)
            if value != 0 {

                switch textField.tag {
                case 1: ///Body Measures
                    //Peso
                    let type = MeasuresType.bodyMeasures.rawValue
                    let index = NSNumber(value: textField.tag).int64Value
                    self.saveNewMessure(newMeasure, type: type, title: "Peso", value: value, index: index)
                case 2:
                    //Altura
                    let type = MeasuresType.bodyMeasures.rawValue
                    let index = NSNumber(value: textField.tag).int64Value
                    self.saveNewMessure(newMeasure, type: type, title: "Altura", value: value, index: index)
                case 3:
                    //%Gordura
                    let type = MeasuresType.bodyMeasures.rawValue
                    let index = NSNumber(value: textField.tag).int64Value
                    self.saveNewMessure(newMeasure, type: type, title: "% Gordura", value: value, index: index)
                default:
                    break
                }
            }
        }
    }
    do {
        try context.save()

        guard let navigation = navigationController else {return}
        navigation.popViewController(animated: true)

        self.delegate?.didFinishUpdates(finished: true)

    } catch let error {
        print("Error Saving Measures Values: \(error)")
    }
}

}

This is my cellForRowAt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: MeasureCell.identifier, for: indexPath) as! MeasureCell
    let measures = fetchedRCAllMeasuresByDay.object(at: indexPath)
    cell.setupMeasureCell(measure: measures)
    return cell
}

I've checked if myTableView.reloadData() has been called in viewWillApperar and I confirmed that.

Here are my methods setupTableView and setupCollectionView in my class MeasureController:

private func setupTableView() {
    myTableView.backgroundColor = Theme.background
    myTableView.separatorStyle = .none
    myTableView.tableFooterView = UIView()
    myTableView.delegate = self
    myTableView.dataSource = self
    myTableView.rowHeight = UITableView.automaticDimension
    myTableView.estimatedRowHeight = 80
    myTableView.register(MeasureCell.nib, forCellReuseIdentifier: MeasureCell.identifier)
}

private func setupCollectionView() {
    myCollectionView.backgroundColor = Theme.background
    myCollectionView.delegate = self
    myCollectionView.dataSource = self        
    myCollectionView.register(UINib(nibName: "DateCollectionCell", bundle: nil), forCellWithReuseIdentifier: cellCollectionViewID)

    //Set Collection View Cell Aligment
    let alignedFlowLayout = AlignedCollectionViewFlowLayout(horizontalAlignment: .right, verticalAlignment: .top)
    alignedFlowLayout.scrollDirection = .horizontal
    myCollectionView.collectionViewLayout = alignedFlowLayout
}

enter image description here

==============================================

This is my NSFetechedResultsControllerDelegate fixed:

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
}

}

And here is the link for the video with the new app behaviour, after fixed the NSFRCD.

New App Behaviour

I found that cellForRowAt is not called after new data is added as soon as old data is deleted. Although numberOfSections has been called, the value is zero. But if you go back to the previous view and re-enter MeasureView, numberOfSections will have a correct value, in other words, numberOfSections will be nonzero.

I've tried to use delegates and callbacks to reload myTableView but I didn't success.

Upvotes: 0

Views: 558

Answers (0)

Related Questions