Digital ACT189 defect CXTDT-618532: Refresh list identifiers on stack changes.

This commit is contained in:
Hedden, Kyle Matthew 2024-09-20 16:36:13 -04:00
parent 02a2da7f0a
commit bc4db7fe68
2 changed files with 37 additions and 9 deletions

View File

@ -84,6 +84,7 @@ public extension ModelRegistry {
let type = try ModelRegistry.getHandler(model) as! MoleculeViewProtocol.Type
return type
} catch {
// TODO: Wrong level to log. Barf so we can get more context on who is asking for a molecule.
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
}

View File

@ -102,7 +102,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
guard let molecules else { return }
// For updating individual specfied molecules. (Not a full table reload done in the base class.) These molecule types should remain the same type by replacement standards.
// For updating individual specfied molecules. (Not a full table reload done in the base class.)
molecules.forEach({ molecule in
// Replace any top level cell data if required.
if let index = moleculesInfo?.firstIndex(where: { $0.molecule.id == molecule.id }) {
@ -256,7 +256,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
guard let moleculesInfo = moleculesInfo else { return }
let indicies = moleculesInfo.indices.filter({ index -> Bool in
// Deep search to find any updated molecules under the top level list models.
var indicies = moleculesInfo.indices.filter({ index -> Bool in
return moleculesInfo[index].molecule.findFirstMolecule(by: { existingMolecule in
molecules.contains { newMolecule in
existingMolecule.moleculeName == newMolecule.moleculeName && equal(moleculeA: existingMolecule, moleculeB: newMolecule)
@ -264,21 +265,47 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}) != nil
})
// Refresh cell identifers. 1st partition are those that don't need to be reloaded. 2nd partition are those that do need a complete reload.
let partionedIndex = indicies.partition { index in
guard let refreshedMoleculeInfo = self.moleculesInfo?[safe: index],
let latestMoleculeInfo = createMoleculeInfo(with: refreshedMoleculeInfo.molecule)
else { return true }
if refreshedMoleculeInfo.identifier == latestMoleculeInfo.identifier {
return false
} else {
tableView.register(latestMoleculeInfo.class, forCellReuseIdentifier: latestMoleculeInfo.identifier)
self.moleculesInfo?[index].identifier = latestMoleculeInfo.identifier
self.moleculesInfo?[index].class = latestMoleculeInfo.class
return true
}
}
// Refresh the cell. (reload loses cell selection)
let selectedIndex = tableView.indexPathForSelectedRow
let indexPaths = indicies.map {
return IndexPath(row: $0, section: 0)
}
debugLog("Refreshing rows \(indexPaths.map { $0.row })")
let refreshRows = Array(indexPaths[..<partionedIndex])
let reloadRows = Array(indexPaths[partionedIndex...])
if #available(iOS 15.0, *) {
// All rows should have been layed out already on the first newDataBuildScreen reload with the getMoleculeInfoList call. Therefore, we can be safe to assume the top level cell configuration will not be modified and only the child content will be updated allowing us to leverage this more efficient method.
tableView.reconfigureRows(at: indexPaths)
} else {
// A full reload can cause a flicker / animation. Better to avoid with above reconfigure method.
tableView.reloadRows(at: indexPaths, with: .automatic)
if !refreshRows.isEmpty {
debugLog("Refreshing rows \(refreshRows.map { $0.row })")
if #available(iOS 15.0, *) {
// All rows should have been layed out already on the first newDataBuildScreen reload with the getMoleculeInfoList call. Therefore, we can be safe to assume the top level cell configuration will not be modified and only the child content will be updated allowing us to leverage this more efficient method.
tableView.reconfigureRows(at: refreshRows)
} else {
// A full reload can cause a flicker / animation. Better to avoid with above reconfigure method.
tableView.reloadRows(at: indexPaths, with: .fade)
}
}
if !reloadRows.isEmpty {
debugLog("Reloading rows \(reloadRows.map { $0.row })")
tableView.reloadRows(at: reloadRows, with: .fade)
}
if let selectedIndex = selectedIndex {
tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
}