diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift index f166e9fb..59bf6136 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift @@ -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) } diff --git a/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift b/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift index 9b50a4a2..1f7326fd 100644 --- a/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift +++ b/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift @@ -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 } }