add and remove clean up, tabs addition

This commit is contained in:
Pfeil, Scott Robert 2021-07-26 18:51:22 -04:00
parent e853647367
commit dc12612c6f
11 changed files with 163 additions and 186 deletions

View File

@ -513,6 +513,7 @@
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; };
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */; };
D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */; };
D2E0FFF826AF68530085D696 /* UITableViewRowAnimation+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E0FFF726AF68530085D696 /* UITableViewRowAnimation+Extension.swift */; };
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; };
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; };
@ -1082,6 +1083,7 @@
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplate.swift; sourceTree = "<group>"; };
D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderModel.swift; sourceTree = "<group>"; };
D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainerProtocol.swift; sourceTree = "<group>"; };
D2E0FFF726AF68530085D696 /* UITableViewRowAnimation+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewRowAnimation+Extension.swift"; sourceTree = "<group>"; };
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = "<group>"; };
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = "<group>"; };
@ -1486,6 +1488,7 @@
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */,
D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */,
D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */,
D2E0FFF726AF68530085D696 /* UITableViewRowAnimation+Extension.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -2942,6 +2945,7 @@
BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */,
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
D2E0FFF826AF68530085D696 /* UITableViewRowAnimation+Extension.swift in Sources */,
1D6D258826899B0C00DEBB08 /* ImageButtonModel.swift in Sources */,
AA07EA912510A442009A2AE3 /* StarModel.swift in Sources */,
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,

View File

@ -1,9 +1,9 @@
//
// UITableViewRowAnimation.swift
// UITableViewRowAnimation+Extension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 7/26/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
extension UITableView.RowAnimation: Codable {}

View File

@ -68,22 +68,22 @@ class AccordionListItemModel: MoleculeListItemModel {
extension AccordionListItemModel: PageBehaviorProtocolRequirer {
public func getRequiredBehaviors() -> [PageBehaviorModelProtocol] {
return [AddRemoveMoleculeBehaviorModel()]
return [AddRemoveMoleculesBehaviorModel()]
}
}
extension AccordionListItemModel: AddMolecules {
public func moleculesToAdd() -> ([ListItemModelProtocol & MoleculeModelProtocol], AddMoleculePosition, UITableView.RowAnimation?)? {
public func moleculesToAdd() -> AddMolecules.AddParameters? {
guard !added, selected else { return nil }
added = true
return (molecules, .below, .automatic)
return (molecules, .below)
}
}
extension AccordionListItemModel: RemoveMolecules {
public func moleculesToRemove() -> ([ListItemModelProtocol & MoleculeModelProtocol], UITableView.RowAnimation?)? {
public func moleculesToRemove() -> [ListItemModelProtocol & MoleculeModelProtocol]? {
guard added else { return nil }
added = false
return (molecules, .automatic)
return molecules
}
}

View File

@ -46,9 +46,9 @@
model.selected = accordionButton.isSelected
if accordionButton.isSelected {
MVMCoreActionHandler.shared()?.handleAction(AddMoleculesActionModel.identifier, actionInformation: nil, additionalData: [KeySourceModel: model], delegateObject: delegateObject)
MVMCoreActionHandler.shared()?.asyncHandleAction(with: AddMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject)
} else {
MVMCoreActionHandler.shared()?.handleAction(RemoveMoleculesActionModel.identifier, actionInformation: nil, additionalData: [KeySourceModel: model], delegateObject: delegateObject)
MVMCoreActionHandler.shared()?.asyncHandleAction(with: RemoveMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject)
}
if (accordionListItemModel?.hideLineWhenExpanded ?? false) && (self.bottomSeparatorView?.shouldBeVisible() ?? false) {
@ -60,5 +60,10 @@
super.set(with: model, delegateObject, additionalData)
guard let model = model as? AccordionListItemModel else { return }
accordionButton.isSelected = model.selected
accordionButton.setTitle(accordionButton.isSelected ? "-" : "+", for: .normal)
if (accordionListItemModel?.hideLineWhenExpanded ?? false) && (self.bottomSeparatorView?.shouldBeVisible() ?? false) {
bottomSeparatorView?.isHidden = accordionButton.isSelected
}
}
}

View File

@ -32,10 +32,9 @@ import UIKit
MVMCoreDispatchUtility.performBlock(inBackground: {
if let oldValue = oldValue,
oldValue.count > 0 {
MVMCoreUIActionHandler.shared()?.synchronouslyHandleAction(RemoveMoleculesActionModel.identifier, actionInformation: nil, additionalData: [KeySourceModel: model], delegateObject: self.delegateObject)
MVMCoreActionHandler.shared()?.syncHandleAction(with: RemoveMoleculesActionModel(.fade), additionalData: [KeySourceModel: model], delegateObject: self.delegateObject)
}
MVMCoreActionHandler.shared()?.handleAction(AddMoleculesActionModel.identifier, actionInformation: nil, additionalData: [KeySourceModel: model], delegateObject: self.delegateObject)
MVMCoreActionHandler.shared()?.syncHandleAction(with: AddMoleculesActionModel(.fade), additionalData: [KeySourceModel: model], delegateObject: self.delegateObject)
})
}
}

View File

@ -86,24 +86,24 @@ import Foundation
extension DropDownListItemModel: PageBehaviorProtocolRequirer {
public func getRequiredBehaviors() -> [PageBehaviorModelProtocol] {
return [AddRemoveMoleculeBehaviorModel()]
return [AddRemoveMoleculesBehaviorModel()]
}
}
extension DropDownListItemModel: AddMolecules {
public func moleculesToAdd() -> ([ListItemModelProtocol & MoleculeModelProtocol], AddMoleculePosition, UITableView.RowAnimation?)? {
public func moleculesToAdd() -> AddMolecules.AddParameters? {
guard addedMolecules == nil,
let index = dropDown.selectedIndex else { return nil }
let addedMolecules = molecules[index]
self.addedMolecules = addedMolecules
return (addedMolecules, .below, .fade)
return (addedMolecules, .below)
}
}
extension DropDownListItemModel: RemoveMolecules {
public func moleculesToRemove() -> ([ListItemModelProtocol & MoleculeModelProtocol], UITableView.RowAnimation?)? {
public func moleculesToRemove() -> [ListItemModelProtocol & MoleculeModelProtocol]? {
guard let addedMolecules = addedMolecules else { return nil }
self.addedMolecules = nil
return (addedMolecules, .fade)
return addedMolecules
}
}

View File

@ -17,7 +17,8 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "tabsListItem"
var tabs: TabsModel
var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
private var addedMolecules: [ListItemModelProtocol & MoleculeModelProtocol]?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
@ -70,3 +71,26 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
try container.encodeModels2D(molecules, forKey: .molecules)
}
}
extension TabsListItemModel: PageBehaviorProtocolRequirer {
public func getRequiredBehaviors() -> [PageBehaviorModelProtocol] {
return [AddRemoveMoleculesBehaviorModel()]
}
}
extension TabsListItemModel: AddMolecules {
public func moleculesToAdd() -> AddMolecules.AddParameters? {
guard addedMolecules == nil else { return nil }
let addedMolecules = molecules[tabs.selectedIndex]
self.addedMolecules = addedMolecules
return (addedMolecules, .below)
}
}
extension TabsListItemModel: RemoveMolecules {
public func moleculesToRemove() -> [ListItemModelProtocol & MoleculeModelProtocol]? {
guard let addedMolecules = addedMolecules else { return nil }
self.addedMolecules = nil
return addedMolecules
}
}

View File

@ -55,9 +55,9 @@ import UIKit
// TODO: Move to AddRemoveMoleculeBehaviorModel
extension TabsTableViewCell: TabsDelegate {
public func shouldSelectItem(_ indexPath: IndexPath, tabs: Tabs) -> Bool {
guard indexPath.row != tabs.selectedIndex else { return false }
if let model = tabsListItemModel {
let molecules = model.molecules[tabs.selectedIndex]
delegateObject?.moleculeListDelegate?.removeMolecules(molecules, animation: indexPath.row < tabs.selectedIndex ? .right : .left)
MVMCoreActionHandler.shared()?.asyncHandleAction(with: RemoveMoleculesActionModel(indexPath.row < tabs.selectedIndex ? .right : .left), additionalData: [KeySourceModel: model], delegateObject: delegateObject)
}
previousTabIndex = tabs.selectedIndex
return true
@ -65,12 +65,9 @@ extension TabsTableViewCell: TabsDelegate {
public func didSelectItem(_ indexPath: IndexPath, tabs: Tabs) {
let index = indexPath.row
if let model = tabsListItemModel,
index < model.molecules.count,
let cellIndexPath = delegateObject?.moleculeListDelegate?.getIndexPath(for: model) {
let molecules = model.molecules[index]
delegateObject?.moleculeListDelegate?.addMolecules(molecules, indexPath: cellIndexPath, animation: index < previousTabIndex ? .left : .right)
}
guard let model = tabsListItemModel,
index < model.molecules.count else { return }
MVMCoreActionHandler.shared()?.asyncHandleAction(with: AddMoleculesActionModel(index < previousTabIndex ? .left : .right), additionalData: [KeySourceModel: model], delegateObject: delegateObject)
}
}

View File

@ -182,44 +182,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
// MARK: - MoleculeDelegateProtocol
//--------------------------------------------------
open override func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) {
guard let tableView = tableView else { return }
if let indexPath = tableView.indexPathForRow(at: molecule.center), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
performTableViewUpdates()
}
}
open override func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? {
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
//TODO: check for molecule protocol eqaulity
let json = moleculeInfo.molecule.toJSON()
return json == molecule.toJSON()
}) else { return nil }
return IndexPath(row: index, section: 0)
}
open override func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) {
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
DispatchQueue.main.async {
var indexPaths: [IndexPath] = []
for molecule in molecules {
if let info = self.createMoleculeInfo(with: molecule) {
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
let index = indexPath.row + 1 + indexPaths.count
self.moleculesInfo?.insert(info, at: index)
indexPaths.append(IndexPath(row: index, section: 0))
}
}
guard indexPaths.count > 0 else { return }
self.tableView?.insertRows(at: indexPaths, with: animation)
self.updateViewConstraints()
self.view.layoutIfNeeded()
}
}
open func newData(for molecule: MoleculeModelProtocol) {
//TODO: expand for header, navigation, etc
let json = molecule.toJSON()
@ -252,23 +214,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
}
}
open override func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) {
var indexPaths: [IndexPath] = []
//TODO: check for molecule protocol equality
for molecule in molecules {
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
moleculesInfo?.remove(at: removeIndex)
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
}
}
guard indexPaths.count > 0 else { return }
tableView?.deleteRows(at: indexPaths, with: animation)
updateViewConstraints()
view.layoutIfNeeded()
}
//--------------------------------------------------
// MARK: - Convenience
@ -337,91 +282,57 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}
extension MoleculeListTemplate: MoleculeListProtocol {
open override func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) {
guard let tableView = tableView else { return }
if let indexPath = tableView.indexPathForRow(at: molecule.center), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
performTableViewUpdates()
}
}
open func removeMolecules(at indexPaths: [IndexPath], animation: UITableView.RowAnimation?) {
for (index, indexPath) in indexPaths.sorted().enumerated() {
let removeIndex = indexPath.row - index
moleculesInfo?.remove(at: removeIndex)
}
open override func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? {
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
//TODO: check for molecule protocol eqaulity
let json = moleculeInfo.molecule.toJSON()
return json == molecule.toJSON()
}) else { return nil }
guard let animation = animation,
indexPaths.count > 0 else { return }
tableView?.deleteRows(at: indexPaths, with: animation)
updateViewConstraints()
view.layoutIfNeeded()
}
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation?) {
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
DispatchQueue.main.async {
var indexPaths: [IndexPath] = []
return IndexPath(row: index, section: 0)
}
for molecule in molecules {
if let info = self.createMoleculeInfo(with: molecule) {
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
let index = indexPath.row + indexPaths.count
self.moleculesInfo?.insert(info, at: index)
indexPaths.append(IndexPath(row: index, section: 0))
}
}
open override func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) {
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
DispatchQueue.main.async {
var indexPaths: [IndexPath] = []
guard let animation = animation,
indexPaths.count > 0 else { return }
self.tableView?.insertRows(at: indexPaths, with: animation)
self.updateViewConstraints()
self.view.layoutIfNeeded()
}
}
open func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? {
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
//TODO: check for molecule protocol eqaulity
let json = moleculeInfo.molecule.toJSON()
return json == molecule.toJSON()
}) else { return nil }
return IndexPath(row: index, section: 0)
}
for molecule in molecules {
if let info = self.createMoleculeInfo(with: molecule) {
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
let index = indexPath.row + 1 + indexPaths.count
self.moleculesInfo?.insert(info, at: index)
indexPaths.append(IndexPath(row: index, section: 0))
}
}
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) {
guard let tableView = tableView else { return }
guard indexPaths.count > 0 else { return }
self.tableView?.insertRows(at: indexPaths, with: animation)
self.updateViewConstraints()
self.view.layoutIfNeeded()
}
}
open func newData(for molecule: MoleculeModelProtocol) {
//TODO: expand for header, navigation, etc
let json = molecule.toJSON()
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
//TODO: check for molecule protocol eqaulity
if json == moleculeInfo.molecule.toJSON() {
return true
} else if let parent = moleculeInfo.molecule as? ParentMoleculeModelProtocol {
// Get all molecules of the same type for faster check.
let molecules: [MoleculeModelProtocol] = parent.reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, currentMolecule, depth) in
if currentMolecule.moleculeName == molecule.moleculeName {
return accumulator + [currentMolecule]
}
return accumulator
}
for molecule in molecules {
if json == molecule.toJSON() {
return true
}
}
}
return false
}) else { return }
// Refresh the cell. (reload loses cell selection)
let selectedIndex = tableView.indexPathForSelectedRow
let indexPath = IndexPath(row: index, section: 0)
tableView.reloadRows(at: [indexPath], with: .automatic)
if let selectedIndex = selectedIndex {
tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
}
}
open override func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) {
var indexPaths: [IndexPath] = []
//TODO: check for molecule protocol equality
for molecule in molecules {
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
moleculesInfo?.remove(at: removeIndex)
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
}
}
guard indexPaths.count > 0 else { return }
tableView?.deleteRows(at: indexPaths, with: animation)
updateViewConstraints()
view.layoutIfNeeded()
}
let point = molecule.convert(molecule.bounds.origin, to: tableView)
if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
performTableViewUpdates()
}
}
}

View File

@ -8,25 +8,28 @@
import Foundation
public enum AddMoleculePosition {
public enum AddMoleculesPosition {
case above
case below
}
/// Protocol for adding items to a list
public protocol AddMolecules {
typealias AddParameters = ([ListItemModelProtocol & MoleculeModelProtocol], AddMoleculesPosition)
/// Get the molecules that need to be added, the position to add them to, and the animation to use
func moleculesToAdd() -> ([ListItemModelProtocol & MoleculeModelProtocol], AddMoleculePosition, UITableView.RowAnimation?)?
func moleculesToAdd() -> AddParameters?
}
/// Protocol for removing items to a list
public protocol RemoveMolecules {
/// Get the molecules that need to be removed, and the animation to use
func moleculesToRemove() -> ([ListItemModelProtocol & MoleculeModelProtocol], UITableView.RowAnimation?)?
func moleculesToRemove() -> [ListItemModelProtocol & MoleculeModelProtocol]?
}
public extension AddMolecules {
/// Gets the molecules that need to be added, recursively checking for additional molecules to add.
func getRecursiveMoleculesToAdd() -> ([ListItemModelProtocol & MoleculeModelProtocol], AddMoleculePosition, UITableView.RowAnimation?)? {
/// Convenience function that gets the molecules that need to be added, recursively checking for additional molecules to add.
func getRecursiveMoleculesToAdd() -> AddMolecules.AddParameters? {
guard let moleculesToAdd = moleculesToAdd() else { return nil }
var newMolecules: [ListItemModelProtocol & MoleculeModelProtocol] = []
for molecule in moleculesToAdd.0 {
@ -41,30 +44,30 @@ public extension AddMolecules {
}
newMolecules.append(molecule)
}
return (newMolecules, moleculesToAdd.1, moleculesToAdd.2)
return (newMolecules, moleculesToAdd.1)
}
}
public extension RemoveMolecules {
/// Gets the molecules that need to be removed, recursively checking for additional molecules to remove.
func getRecursiveMoleculesToRemove() -> ([ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation?)? {
/// Convenience function that gets the molecules that need to be removed, recursively checking for additional molecules to remove.
func getRecursiveMoleculesToRemove() -> [ListItemModelProtocol & MoleculeModelProtocol]? {
guard let moleculesToRemove = moleculesToRemove() else { return nil }
var newMolecules: [ListItemModelProtocol & MoleculeModelProtocol] = moleculesToRemove.0
for case let molecule as (ListItemModelProtocol & MoleculeModelProtocol & RemoveMolecules) in moleculesToRemove.0 {
var newMolecules: [ListItemModelProtocol & MoleculeModelProtocol] = moleculesToRemove
for case let molecule as (ListItemModelProtocol & MoleculeModelProtocol & RemoveMolecules) in moleculesToRemove {
guard let moreMolecules = molecule.getRecursiveMoleculesToRemove() else { continue }
newMolecules.append(contentsOf: moreMolecules.0)
newMolecules.append(contentsOf: moreMolecules)
}
return (newMolecules, moleculesToRemove.1)
return newMolecules
}
}
public class AddRemoveMoleculeBehaviorModel: PageBehaviorModelProtocol {
public class AddRemoveMoleculesBehaviorModel: PageBehaviorModelProtocol {
public class var identifier: String { "addRemoveListItemBehavior" }
public var shouldAllowMultipleInstances: Bool { false }
public init() {}
}
public class AddRemoveMoleculeBehavior: PageCustomActionHandlerBehavior {
public class AddRemoveMoleculesBehavior: PageCustomActionHandlerBehavior, PageMoleculeTransformationBehavior {
var delegate: MVMCoreUIDelegateObject?
@ -72,22 +75,34 @@ public class AddRemoveMoleculeBehavior: PageCustomActionHandlerBehavior {
self.delegate = delegateObject
}
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject) {
guard let list = delegate?.moleculeListDelegate else { return }
for case let model as (MoleculeModelProtocol & ListItemModelProtocol & AddMolecules) in rootMolecules {
if let moleculesToAdd = model.getRecursiveMoleculesToAdd(),
let indexPath = list.getAdjustedIndexPath(for: model, position: moleculesToAdd.1) {
list.addMolecules(moleculesToAdd.0, indexPath: indexPath, animation: nil)
}
}
}
public func handleAction(type actionType: String?, information: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) -> Bool {
if actionType == AddMoleculesActionModel.identifier {
guard let list = delegate?.moleculeListDelegate,
let model = additionalData?[KeySourceModel] as? (ListItemModelProtocol & MoleculeModelProtocol & AddMolecules),
let moleculesToAdd = model.getRecursiveMoleculesToAdd(),
let indexPath = list.getAdjustedIndexPath(for: model, position: moleculesToAdd.1) else { return true }
let indexPath = list.getAdjustedIndexPath(for: model, position: moleculesToAdd.1),
let animation = information?["animation"] as? Int else { return true }
DispatchQueue.main.async {
list.addMolecules(moleculesToAdd.0, indexPath: indexPath, animation: moleculesToAdd.2)
list.addMolecules(moleculesToAdd.0, indexPath: indexPath, animation: UITableView.RowAnimation(rawValue: animation))
}
return true
} else if actionType == RemoveMoleculesActionModel.identifier {
guard let list = delegate?.moleculeListDelegate,
let model = additionalData?[KeySourceModel] as? (ListItemModelProtocol & MoleculeModelProtocol & RemoveMolecules),
let moleculesToRemove = model.getRecursiveMoleculesToRemove() else { return true }
let moleculesToRemove = model.getRecursiveMoleculesToRemove(),
let animation = information?["animation"] as? Int else { return true }
DispatchQueue.main.async {
list.removeMolecules(moleculesToRemove.0, animation: moleculesToRemove.1)
list.removeMolecules(moleculesToRemove, animation: UITableView.RowAnimation(rawValue: animation))
}
return true
}
@ -97,7 +112,7 @@ public class AddRemoveMoleculeBehavior: PageCustomActionHandlerBehavior {
private extension MoleculeListProtocol {
/// Convenience function to get the index path adjusted for position.
func getAdjustedIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol, position: AddMoleculePosition) -> IndexPath? {
func getAdjustedIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol, position: AddMoleculesPosition) -> IndexPath? {
guard let indexPath = getIndexPath(for: molecule) else { return nil }
if position == .below {
return IndexPath(row: indexPath.row + 1, section: indexPath.section)
@ -109,6 +124,7 @@ private extension MoleculeListProtocol {
public class AddMoleculesActionModel: ActionModelProtocol {
public static var identifier: String = "addMoleculesAction"
public var actionType: String = AddMoleculesActionModel.identifier
public var animation: UITableView.RowAnimation = .automatic
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
@ -116,15 +132,26 @@ public class AddMoleculesActionModel: ActionModelProtocol {
// MARK: - Initializer
//--------------------------------------------------
public init(_ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
public init(_ animation: UITableView.RowAnimation, extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
self.animation = animation
self.extraParameters = extraParameters
self.analyticsData = analyticsData
}
public required init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let animation = try typeContainer.decodeIfPresent(UITableView.RowAnimation.self, forKey: .animation) {
self.animation = animation
}
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
}
}
public class RemoveMoleculesActionModel: ActionModelProtocol {
public static var identifier: String = "removeMoleculesAction"
public var actionType: String = RemoveMoleculesActionModel.identifier
public var animation: UITableView.RowAnimation = .automatic
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
@ -132,8 +159,18 @@ public class RemoveMoleculesActionModel: ActionModelProtocol {
// MARK: - Initializer
//--------------------------------------------------
public init(_ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
public init(_ animation: UITableView.RowAnimation, extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
self.animation = animation
self.extraParameters = extraParameters
self.analyticsData = analyticsData
}
public required init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let animation = try typeContainer.decodeIfPresent(UITableView.RowAnimation.self, forKey: .animation) {
self.animation = animation
}
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
}
}

View File

@ -222,7 +222,7 @@ open class CoreUIModelMapping: ModelMapping {
open class func registerBehaviors() {
ModelRegistry.register(handler: ScreenBrightnessModifierBehavior.self, for: ScreenBrightnessModifierBehaviorModel.self)
ModelRegistry.register(handler: PageGetContactBehavior.self, for: PageGetContactBehaviorModel.self)
ModelRegistry.register(handler: AddRemoveMoleculeBehavior.self, for: AddRemoveMoleculeBehaviorModel.self)
ModelRegistry.register(handler: AddRemoveMoleculesBehavior.self, for: AddRemoveMoleculesBehaviorModel.self)
}
open override class func registerActions() {