From 90e6dfd08429b38e63e90110acb827230c1ab017 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 24 Jun 2021 13:59:37 -0400 Subject: [PATCH] nav dev --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + .../Atoms/Selectors/CheckboxModel.swift | 2 +- .../Atomic/Atoms/Selectors/ToggleModel.swift | 2 +- .../SelectAllNavigationLabelButton.swift | 82 +++++++++++++++++++ .../Behaviors/SelectAllBoxesBehavior.swift | 61 ++++---------- .../OtherHandlers/CoreUIModelMapping.swift | 1 + 6 files changed, 105 insertions(+), 47 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b90b6f5e..281a6ffc 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ 0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; }; + 0A423A202684E7A0008EC258 /* SelectAllNavigationLabelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A423A1F2684E7A0008EC258 /* SelectAllNavigationLabelButton.swift */; }; 0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */; }; 0A51F3E32475CB73002E08B6 /* LoadingSpinner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */; }; 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; @@ -636,6 +637,7 @@ 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryFieldModel.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; + 0A423A1F2684E7A0008EC258 /* SelectAllNavigationLabelButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectAllNavigationLabelButton.swift; sourceTree = ""; }; 0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingSpinnerModel.swift; sourceTree = ""; }; 0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingSpinner.swift; sourceTree = ""; }; 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; @@ -1755,6 +1757,7 @@ D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */, D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */, D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */, + 0A423A1F2684E7A0008EC258 /* SelectAllNavigationLabelButton.swift */, ); path = Buttons; sourceTree = ""; @@ -2730,6 +2733,7 @@ D264FA8E243BCD9A00D98315 /* CollectionTemplate.swift in Sources */, 0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */, AA633B3124989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift in Sources */, + 0A423A202684E7A0008EC258 /* SelectAllNavigationLabelButton.swift in Sources */, 8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */, D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */, D2FD4A4925199BD9000C28A9 /* AccessibilityProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 4efa53ec..87c4568d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -7,7 +7,7 @@ // -@objcMembers public class CheckboxModel: NSObject, MoleculeModelProtocol, SelectableMoleculeModel, FormFieldProtocol { +@objcMembers public class CheckboxModel: NSObject, MoleculeModelProtocol, SelectableMoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift index 88f193f5..0fb42632 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift @@ -7,7 +7,7 @@ // -public class ToggleModel: NSObject, MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol, SelectableMoleculeModel { +public class ToggleModel: NSObject, MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol, SelectableMoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift new file mode 100644 index 00000000..f166e9fb --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/SelectAllNavigationLabelButton.swift @@ -0,0 +1,82 @@ +// +// SelectAllNavigationLabelButton.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 6/24/21. +// Copyright © 2021 Verizon Wireless. All rights reserved. +// + + +public class SelectAllNavigationLabelButton: NavigationButtonModelProtocol, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public var backgroundColor: Color? + public static var identifier: String = "selectAllNavigationLabelButton" + public var accessibilityIdentifier: String? + public var willSelect: Bool + public var selectAllTitle: String = "Select All" + public var deselectAllTitle: String = "Deselect All" + public var action: ActionModelProtocol + + public var selectionTitle: String { + willSelect ? selectAllTitle : deselectAllTitle + } + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + + public init(willSelect: Bool, selectAllTitle: String, deselectAllTitle: String, action: ActionModelProtocol) { + self.willSelect = willSelect + self.action = action + self.selectAllTitle = selectAllTitle + self.deselectAllTitle = deselectAllTitle + } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case moleculeName + case accessibilityIdentifier + case willSelect + case selectAllTitle + case deselectAllTitle + case action + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + required public init(from decoder: Decoder) throws { + 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) + willSelect = try typeContainer.decode(Bool.self, forKey: .willSelect) + action = try typeContainer.decodeModel(codingKey: .action) + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + 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(willSelect, forKey: .willSelect) + try container.encodeModel(action, forKey: .action) + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Convenience function that creates a BarButtonItem for the model. + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem { + LabelBarButtonItem.create(with: selectionTitle, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + } +} diff --git a/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift b/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift index d16c6cd6..9b50a4a2 100644 --- a/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift +++ b/MVMCoreUI/Behaviors/SelectAllBoxesBehavior.swift @@ -16,36 +16,7 @@ public class SelectAllBoxesBehaviorModel: PageBehaviorModelProtocol { public class var identifier: String { "pageSelectAllBoxesBehavior" } public var shouldAllowMultipleInstances: Bool { false } - public var selectAllTitle: String = "Select All" - public var deselectAllTitle: String = "Deselect All" public init() { } - - //-------------------------------------------------- - // MARK: - Codable - //-------------------------------------------------- - - private enum CodingKeys: String, CodingKey { - case selectAllTitle - case deselectAllTitle - } - - required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - - if let selectAllTitle = try typeContainer.decodeIfPresent(String.self, forKey: .selectAllTitle) { - self.selectAllTitle = selectAllTitle - } - - if let deselectAllTitle = try typeContainer.decodeIfPresent(String.self, forKey: .deselectAllTitle) { - self.deselectAllTitle = deselectAllTitle - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(selectAllTitle, forKey: .selectAllTitle) - try container.encode(deselectAllTitle, forKey: .deselectAllTitle) - } } /// Selects all the control models presented on a page. @@ -83,7 +54,7 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject) { - let selectableModels: [(NSObject & SelectableMoleculeModel)] = rootMolecules.allMoleculesOfType() + let selectableModels: [(NSObject & SelectableMoleculeModelProtocol)] = rootMolecules.allMoleculesOfType() guard !selectableModels.isEmpty else { return } @@ -95,7 +66,7 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu } } - func setObserver(_ model: T, fieldKey: String) where T: (NSObject & SelectableMoleculeModel) { + func setObserver(_ model: T, fieldKey: String) where T: (NSObject & SelectableMoleculeModelProtocol) { observers[fieldKey] = model.observe(\.selected, options: [.new]) { [weak self] model, change in guard let self = self, @@ -137,7 +108,7 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu // Verify we have the correct action type and necessary values. guard actionType == "selectAllBoxes", - let selectableModels: [SelectableMoleculeModel] = delegate?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(), + let selectableModels: [SelectableMoleculeModelProtocol] = delegate?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(), !selectableModels.isEmpty else { return false } @@ -170,20 +141,20 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu /// 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 +// let navButtonTitle: String? = didSelectAllState ? model.deselectAllTitle : model.selectAllTitle + // TODO: update - MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in - guard let controller = self?.delegate?.moleculeDelegate as? ViewController else { return } - controller.handleNewDataAndUpdateUI() - - if MVMCoreUIUtility.getCurrentVisibleController() == controller { - controller.navigationItem.rightBarButtonItem?.title = navButtonTitle - controller.manager?.refreshNavigationUI() - } - }) +// 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 +// } +// }) } /// Convenience function for readability to confirmt he state of the behavior. @@ -201,14 +172,14 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior, PageMolecu /// 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: SelectableMoleculeModel) -> Bool { + func toSelect(model: SelectableMoleculeModelProtocol) -> Bool { didSelectAllState && !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: SelectableMoleculeModel) -> Bool { + func toDeselect(model: SelectableMoleculeModelProtocol) -> Bool { !didSelectAllState && model.selected } } diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 437b2e01..f33943e1 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -129,6 +129,7 @@ open class CoreUIModelMapping: ModelMapping { try? ModelRegistry.register(NavigationItemModel.self) try? ModelRegistry.register(NavigationImageButtonModel.self) try? ModelRegistry.register(NavigationLabelButtonModel.self) + try? ModelRegistry.register(SelectAllNavigationLabelButton.self) // MARK:- Other Organisms try? ModelRegistry.register(handler: Carousel.self, for: CarouselModel.self)