Digital PCT265 defect MVAPCT-272: Adjust molecule adds and swapping.

This commit is contained in:
Hedden, Kyle Matthew 2024-09-13 17:23:00 -04:00
parent bbadce4dc7
commit a50c6ffed5

View File

@ -8,7 +8,7 @@
import UIKit
public struct MoleculeInfo: Hashable {
public struct MoleculeInfo: Hashable, CustomDebugStringConvertible {
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
@ -44,6 +44,10 @@ public struct MoleculeInfo: Hashable {
}
})
}
public var debugDescription: String {
return "\(Self.self) \(id)"
}
}
extension Array where Element == MoleculeInfo {
@ -52,14 +56,15 @@ extension Array where Element == MoleculeInfo {
filter { listItemRef in molecules.contains { $0.id == listItemRef.model.id } }
}
func registerTypes(with tableView: UITableView) {
func registerTypes(with tableView: UITableView) -> [MoleculeInfo] {
forEach { tableView.register($0.cellType, forCellReuseIdentifier: $0.cellReuseId) }
return self
}
}
extension Array where Element == ListItemModelProtocol & MoleculeModelProtocol {
func asMoleculeInfoRef() -> [MoleculeInfo] {
compactMap { MoleculeInfo(listItemModel: $0) }
func asMoleculeInfoRef(delegateObject: MVMCoreUIDelegateObject?) -> [MoleculeInfo] {
compactMap { MoleculeInfo(listItemModel: $0, delegateObject: delegateObject) }
}
}
@ -208,16 +213,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
// MARK: - Table View
//--------------------------------------------------
open override func registerWithTable() {
super.registerWithTable()
for moleculeInfo in dataSource.snapshot().itemIdentifiers {
tableView?.register(moleculeInfo.cellType, forCellReuseIdentifier: moleculeInfo.cellReuseId)
}
}
open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return (dataSource.itemIdentifier(for: indexPath)?.model as? GoneableProtocol)?.gone == true ? 0 : UITableView.automaticDimension
return dataSource.itemIdentifier(for: indexPath)?.model.gone == true ? 0 : UITableView.automaticDimension
}
open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
@ -227,28 +224,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
return estimatedHeight
}
// open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// debugLog("Number of rows: \(moleculesInfo?.count ?? 0)")
// return moleculesInfo?.count ?? 0
// }
// open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
// guard let moleculeInfo = getMoleculeInfo(for: indexPath),
// let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
// else { return UITableViewCell() }
// cell.isHidden = (getMoleculeInfo(for: indexPath)?.molecule as? GoneableProtocol)?.gone == true
// (cell as? MoleculeViewProtocol)?.reset()
// (cell as? MoleculeListCellProtocol)?.setLines(with: templateModel?.line, delegateObject: delegateObjectIVar, additionalData: nil, indexPath: indexPath)
// if let moleculeView = cell as? MoleculeViewProtocol {
// updateMoleculeView(moleculeView, from: moleculeInfo.molecule)
// }
// (cell as? MVMCoreViewProtocol)?.updateView(tableView.bounds.width)
// // Neded to fix an apple defect where the cell is not the correct size on certain devices for certain cells
// cell.setNeedsLayout()
// return cell
// }
open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
(cell as? MoleculeListCellProtocol)?.willDisplay()
@ -327,10 +302,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
var snapshot = dataSource.snapshot()
let updatedListItems: [MoleculeInfo] = snapshot.itemIdentifiers.compactMap { listItemRef -> MoleculeInfo? in
var listItemRef = listItemRef
guard let matchedMolecule = listItemRef.contains(oneOf: molecules) else { return nil }
if let matchedMolecule = matchedMolecule as? (ListItemModelProtocol & MoleculeModelProtocol), listItemRef.doesMatch(matchedMolecule) {
var listItemRef = listItemRef
listItemRef.model = matchedMolecule // Replace the top level molecule if it changed.
return listItemRef
}
return listItemRef
}
@ -367,38 +343,13 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
// MARK: - Convenience
//--------------------------------------------------
/// Returns the (identifier, class) of the molecule for the indexPath.
// func getMoleculeInfo(for indexPath: IndexPath) -> MoleculeInfo? {
// moleculesInfo?[safe: indexPath.row]
// }
/// Sets up the molecule list and ensures no errors loading all content.
// func getMoleculeInfoList() -> [MoleculeInfo]? {
//
// var moleculeList: [MoleculeInfo] = []
//
// if let molecules = templateModel?.molecules {
// for molecule in molecules {
// if let info = MoleculeInfo(with: molecule) {
// moleculeList.append(info)
// }
// }
// }
//
// return moleculeList.count > 0 ? moleculeList : nil
// }
/// Sets up the header, footer, molecule list and ensures no errors loading all content.
func setup() {
guard let listItems = templateModel?.molecules?.compactMap({ MoleculeInfo(listItemModel: $0, delegateObject: delegateObject() as? MVMCoreUIDelegateObject)}) else {
debugLog("There is no data to display.")
return
}
guard let listItems = templateModel?.molecules?.asMoleculeInfoRef(delegateObject: delegateObjectIVar).registerTypes(with: tableView) else { return }
var initialDataSnapshot = ListDataSnapshot()
initialDataSnapshot.appendSections([0])
initialDataSnapshot.appendItems(listItems)
dataSource.apply(initialDataSnapshot)
dataSource.apply(initialDataSnapshot, animatingDifferences: false)
}
/// Adds modules from requiredModules() to the MVMCoreViewControllerMapping.requiredModules map.
@ -448,7 +399,7 @@ extension MoleculeListTemplate: MoleculeListProtocol {
/// Convenience function that removes the passed molecule
public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation?) {
var snapshot = dataSource.snapshot()
snapshot.deleteItems(molecules.asMoleculeInfoRef())
snapshot.deleteItems(molecules.asMoleculeInfoRef(delegateObject: delegateObjectIVar))
dataSource.apply(snapshot, animatingDifferences: true) {
self.updateViewConstraints()
self.view.setNeedsLayout()
@ -456,20 +407,30 @@ extension MoleculeListTemplate: MoleculeListProtocol {
}
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation?) {
let additionalMoleculesRef = molecules.asMoleculeInfoRef(delegateObject: delegateObjectIVar).registerTypes(with: tableView)
var snapshot = dataSource.snapshot()
guard let listItemRef = snapshot.itemIdentifiers[safe: indexPath.row] else { return }
snapshot.insertItems(molecules.asMoleculeInfoRef(), afterItem: listItemRef)
dataSource.apply(snapshot, animatingDifferences: true) {
debugLog("[ADD] State before: \(snapshot.itemIdentifiers)")
if let targetMoleculeRef = snapshot.itemIdentifiers[safe: indexPath.row] {
snapshot.insertItems(additionalMoleculesRef, beforeItem: targetMoleculeRef)
debugLog("[ADD] Applying: \(snapshot.itemIdentifiers)")
} else {
snapshot.appendItems(additionalMoleculesRef)
debugLog("[ADD] Applying: \(snapshot.itemIdentifiers)")
}
dataSource.apply(snapshot, animatingDifferences: false) {
self.updateViewConstraints()
self.view.setNeedsLayout()
}
}
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], after molecule: (ListItemModelProtocol & MoleculeModelProtocol), animation: UITableView.RowAnimation?) {
guard let listMoleculeRef = MoleculeInfo(listItemModel: molecule) else { return }
guard let targetMoleculeRef = MoleculeInfo(listItemModel: molecule) else { return }
let additionalMoleculesRef = molecules.asMoleculeInfoRef(delegateObject: delegateObjectIVar).registerTypes(with: tableView)
var snapshot = dataSource.snapshot()
snapshot.insertItems(molecules.asMoleculeInfoRef(), afterItem: listMoleculeRef)
dataSource.apply(snapshot, animatingDifferences: true) {
debugLog("[ADD] State before: \(snapshot.itemIdentifiers)")
snapshot.insertItems(additionalMoleculesRef, afterItem: targetMoleculeRef)
debugLog("[ADD] Applying: \(snapshot.itemIdentifiers)")
dataSource.apply(snapshot, animatingDifferences: false) {
self.updateViewConstraints()
self.view.setNeedsLayout()
}
@ -478,27 +439,29 @@ extension MoleculeListTemplate: MoleculeListProtocol {
public func swapMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], with replacements: [ListItemModelProtocol & MoleculeModelProtocol], at indexPath: IndexPath, animation: UITableView.RowAnimation?) {
swapMolecules(molecules, with: replacements, after: dataSource.snapshot().itemIdentifiers[safe: indexPath.row] as? (ListItemModelProtocol & MoleculeModelProtocol), animation: animation)
}
public func swapMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], with replacements: [ListItemModelProtocol & MoleculeModelProtocol], after targetMolecule: (ListItemModelProtocol & MoleculeModelProtocol)?, animation: UITableView.RowAnimation?) {
guard let tableView else { return }
let removingRefs = molecules.asMoleculeInfoRef()
var snapshot = dataSource.snapshot()
let replacementRefs = molecules.asMoleculeInfoRef()
replacementRefs.registerTypes(with: tableView)
if let targetMolecule, let targetRef = MoleculeInfo(listItemModel: targetMolecule) {
snapshot.insertItems(replacementRefs, afterItem: targetRef)
} else if let targetRef = removingRefs.first {
snapshot.insertItems(replacementRefs, beforeItem: targetRef)
}
debugLog("[SWAP] State before: \(snapshot.itemIdentifiers)")
let removingRefs = molecules.asMoleculeInfoRef(delegateObject: delegateObjectIVar)
snapshot.deleteItems(removingRefs)
dataSource.apply(snapshot) {
debugLog("[SWAP] State after delete: \(snapshot.itemIdentifiers)")
if let targetMolecule, let targetRef = MoleculeInfo(listItemModel: targetMolecule) {
let replacementRefs = molecules.asMoleculeInfoRef(delegateObject: delegateObjectIVar).registerTypes(with: tableView)
snapshot.insertItems(replacementRefs, afterItem: targetRef)
}
debugLog("[SWAP] Applying: \(snapshot.itemIdentifiers)")
dataSource.defaultRowAnimation = animation ?? .automatic
dataSource.apply(snapshot ) {
self.dataSource.defaultRowAnimation = .automatic
self.updateViewConstraints()
self.view.setNeedsLayout()
}