Reputation: 87
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
}
==============================================
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.
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