select all behavior.

This commit is contained in:
Kevin G Christiano 2021-06-24 16:30:52 -04:00
parent 1109931d8e
commit e79c159138
2 changed files with 42 additions and 34 deletions

View File

@ -15,7 +15,7 @@ public class SelectAllNavigationLabelButton: NavigationButtonModelProtocol, Mole
public var backgroundColor: Color?
public static var identifier: String = "selectAllNavigationLabelButton"
public var accessibilityIdentifier: String?
public var willSelect: Bool
public var willSelect: Bool = true
public var selectAllTitle: String = "Select All"
public var deselectAllTitle: String = "Deselect All"
public var action: ActionModelProtocol
@ -44,7 +44,7 @@ public class SelectAllNavigationLabelButton: NavigationButtonModelProtocol, Mole
case accessibilityIdentifier
case willSelect
case selectAllTitle
case deselectAllTitle
case deSelectAllTitle
case action
}
@ -56,7 +56,7 @@ public class SelectAllNavigationLabelButton: NavigationButtonModelProtocol, Mole
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
selectAllTitle = try typeContainer.decode(String.self, forKey: .selectAllTitle)
deselectAllTitle = try typeContainer.decode(String.self, forKey: .deselectAllTitle)
deselectAllTitle = try typeContainer.decode(String.self, forKey: .deSelectAllTitle)
willSelect = try typeContainer.decode(Bool.self, forKey: .willSelect)
action = try typeContainer.decodeModel(codingKey: .action)
}
@ -66,7 +66,7 @@ public class SelectAllNavigationLabelButton: NavigationButtonModelProtocol, Mole
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(selectAllTitle, forKey: .selectAllTitle)
try container.encode(deselectAllTitle, forKey: .deselectAllTitle)
try container.encode(deselectAllTitle, forKey: .deSelectAllTitle)
try container.encode(willSelect, forKey: .willSelect)
try container.encodeModel(action, forKey: .action)
}

View File

@ -26,7 +26,10 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu
//--------------------------------------------------
/// Status of the select all behavior. Initially false as the action has not been enaged.
var didSelectAllState = false
var willSelectAllState: Bool {
get { getSelectAllNavbutton()?.willSelect ?? false }
set { getSelectAllNavbutton()?.willSelect = newValue }
}
/// Reference to the general PageBehaviorModel.
var model: PageBehaviorModelProtocol
@ -57,7 +60,7 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu
let selectableModels: [(NSObject & SelectableMoleculeModelProtocol)] = rootMolecules.allMoleculesOfType()
guard !selectableModels.isEmpty else { return }
for model in selectableModels {
if let key = (model as? FormFieldProtocol)?.fieldKey {
valuesMirror[key] = model.selected
@ -77,10 +80,10 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu
// If all are models are in the opposite state of the behavior, then realign.
if self.selectAllIsMisaligned() {
self.realignPageBehavior(asSelectAll: true)
self.realignPageBehaviorAs(willSelectAll: false)
} else if self.deselectAllIsMisaligned() {
self.realignPageBehavior(asSelectAll: false)
self.realignPageBehaviorAs(willSelectAll: true)
}
}
}
@ -112,13 +115,13 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu
!selectableModels.isEmpty
else { return false }
// Flip the selected state of the behavior.
didSelectAllState.toggle()
// Hold value dues to asynch behavior of page refreshing.
let newSelectedState = willSelectAllState
// Iterate through selectable molecules.
for selectableModel in selectableModels {
if toSelect(model: selectableModel) || toDeselect(model: selectableModel) {
selectableModel.selected = didSelectAllState
selectableModel.selected = newSelectedState
}
}
@ -130,56 +133,61 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu
// MARK: - Methods
//--------------------------------------------------
func getSelectAllNavbutton() -> SelectAllNavigationLabelButton? {
guard let controller = self.delegate?.moleculeDelegate as? PageProtocol,
let rightNavButtonModels = controller.pageModel?.navigationBar?.additionalRightButtons
else { return nil }
var navButton: SelectAllNavigationLabelButton? = nil
for navModel in rightNavButtonModels {
if let model = navModel as? SelectAllNavigationLabelButton {
navButton = model
}
}
return navButton
}
/// In the event that the user manually selects or deselects all `SelectableMoleculeModel`
/// the behavior will need to reflect the inverse of its previously expected action.
/// Initiates the navigation and page behavior realignment
/// - Parameter asSelectAll: The actual value didSelectAllState ought to be.
func realignPageBehavior(asSelectAll: Bool) {
didSelectAllState = asSelectAll
/// - Parameter asSelectAll: The actual value willSelectAllState ought to be.
func realignPageBehaviorAs(willSelectAll: Bool) {
willSelectAllState = willSelectAll
updatePageNavigationUI()
}
/// Updates the navigation UI to correctly reflect the behavior's state.
func updatePageNavigationUI() {
guard let model = model as? SelectAllBoxesBehaviorModel else { return }
// let navButtonTitle: String? = didSelectAllState ? model.deselectAllTitle : model.selectAllTitle
// TODO: update
// MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
// guard let controller = self?.delegate?.moleculeDelegate as? PageProtocol else { return }
// controller.handleNewDataAndUpdateUI()
// let n = controller.getNavigationModel()
// let r = n?.additionalRightButtons
// for i in r! {
// i.moleculeName
// }
// })
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
(self?.delegate?.moleculeDelegate as? ViewController)?.handleNewDataAndUpdateUI()
})
}
/// Convenience function for readability to confirmt he state of the behavior.
/// - Returns: Boolean indicating that the behavior's `didSelectAllState` is false while all model values are true (selected).
/// - Returns: Boolean indicating that the behavior's `willSelectAllState` is false while all model values are true (selected).
func selectAllIsMisaligned() -> Bool {
!didSelectAllState && valuesMirror.values.allSatisfy { $0 == true }
willSelectAllState && valuesMirror.values.allSatisfy { $0 == true }
}
/// Convenience function for readability to confirmt he state of the behavior.
/// - Returns: Boolean indicating that the behavior's `didSelectAllState` is true while all model values are false (deselected).
/// - Returns: Boolean indicating that the behavior's `willSelectAllState` is true while all model values are false (deselected).
func deselectAllIsMisaligned() -> Bool {
didSelectAllState && valuesMirror.values.allSatisfy { $0 == false }
!willSelectAllState && valuesMirror.values.allSatisfy { $0 == false }
}
/// Convenience function making it easier to read if a current selectable model should be acted on.
/// - Parameter model: A model object assined to the SelectableModel protocol
/// - Returns: Boolean determining if the passed model should be selected.
func toSelect(model: SelectableMoleculeModelProtocol) -> Bool {
didSelectAllState && !model.selected
willSelectAllState && !model.selected
}
/// Convenience function making it easier to read if a current selectable model should be acted on.
/// - Parameter model: A model object assined to the SelectableModel protocol
/// - Returns: Boolean determining if the passed model should be deselected.
func toDeselect(model: SelectableMoleculeModelProtocol) -> Bool {
!didSelectAllState && model.selected
!willSelectAllState && model.selected
}
}