From 72f1d48eebe4196e51e15cbf0c185d55101a1135 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 11 May 2020 11:52:18 -0400 Subject: [PATCH 01/67] page behavior protocol --- MVMCoreUI.xcodeproj/project.pbxproj | 18 ++++- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 + .../TemplateModelProtocol.swift | 2 +- .../Atomic/Templates/TemplateModel.swift | 6 +- .../MVMControllerModelProtocol.swift | 2 +- .../BaseControllers/ViewController.swift | 17 +++++ MVMCoreUI/Behaviors/PageBehavior.swift | 44 ++++++++++++ .../ScreenBrightnessModifierBehavior.swift | 70 +++++++++++++++++++ 8 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 MVMCoreUI/Behaviors/PageBehavior.swift create mode 100644 MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 3915b055..6bae9611 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -108,6 +108,8 @@ 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; }; 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; }; 279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; }; + 27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehavior.swift */; }; + 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; 522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; }; @@ -519,6 +521,8 @@ 0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = ""; }; 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = ""; }; 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = ""; }; + 27F973522466074500CAB5C5 /* PageBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehavior.swift; sourceTree = ""; }; + 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = ""; }; @@ -948,6 +952,15 @@ path = Adapters; sourceTree = ""; }; + 27F973512466071600CAB5C5 /* Behaviors */ = { + isa = PBXGroup; + children = ( + 27F973522466074500CAB5C5 /* PageBehavior.swift */, + 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */, + ); + path = Behaviors; + sourceTree = ""; + }; 5206F150241144A900658DC5 /* Headers */ = { isa = PBXGroup; children = ( @@ -1383,6 +1396,7 @@ D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */ = { isa = PBXGroup; children = ( + 27F973512466071600CAB5C5 /* Behaviors */, D2C78CD324252F4E00B69FDE /* Atomic */, 012A88EF23985E0100FE3DA1 /* CustomPrimitives */, D2B18B7D236090D500A9AEDC /* BaseClasses */, @@ -2103,7 +2117,7 @@ 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */, 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */, D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */, - 8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */, + 8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */, 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */, BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */, 017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */, @@ -2128,6 +2142,7 @@ AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, + 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */, 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */, @@ -2220,6 +2235,7 @@ D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, + 27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index a9e86d50..a77b50f4 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -198,6 +198,9 @@ import Foundation try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionCollapseNotificationModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self) + + // Behaviors + try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self) } /// Convenience function to get required modules for a give model diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index 3ed37d6b..f34c4ebd 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol { +public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, PageBehaviorsTemplateProtocol { var template: String { get } } diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/TemplateModel.swift index 86da1981..864c2bf8 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/TemplateModel.swift @@ -9,6 +9,7 @@ import Foundation @objcMembers public class TemplateModel: MVMControllerModelProtocol { + public class var identifier: String { return "" } @@ -21,7 +22,8 @@ import Foundation public var screenHeading: String? public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? public var formRules: [FormGroupRule]? - + public var behaviors: [PageBehaviorProtocol]? + public init(pageType: String) { self.pageType = pageType } @@ -32,6 +34,7 @@ import Foundation case screenHeading case backgroundColor case formRules + case behaviors case navigationItem } @@ -41,6 +44,7 @@ import Foundation screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) + behaviors = try typeContainer.decodeModelsIfPresent(codingKey: .behaviors) navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem) } diff --git a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift index 579a612e..4ec8ed2c 100644 --- a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift +++ b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift @@ -8,6 +8,6 @@ import Foundation -public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol { +public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorsTemplateProtocol { } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 75cb897c..28aacc6e 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -306,6 +306,18 @@ import UIKit MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) } + + executeBehaviors { (behavior: PageVisibilityBehavior) in + behavior.onPageShown() + } + } + + open override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + executeBehaviors { (behavior: PageVisibilityBehavior) in + behavior.onPageHidden() + } } deinit { @@ -420,4 +432,9 @@ import UIKit selectedField = nil } } + + // MARK: - Behavior Execution + func executeBehaviors(_ behaviorBlock:(_ behavior:T)->Void) { + pageModel?.behaviors?.compactMap({ $0 as? T }).forEach({ behaviorBlock($0) }) + } } diff --git a/MVMCoreUI/Behaviors/PageBehavior.swift b/MVMCoreUI/Behaviors/PageBehavior.swift new file mode 100644 index 00000000..d8fd99a3 --- /dev/null +++ b/MVMCoreUI/Behaviors/PageBehavior.swift @@ -0,0 +1,44 @@ +// +// PageBehaviors.swift +// MVMCoreUI +// +// Created by Kyle on 5/8/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PageBehaviorProtocol: ModelProtocol { + + // The type of rule + var behaviorName: String { get } + +} + +public extension PageBehaviorProtocol { + + var behaviorName: String { + get { return Self.identifier } + } + + static var categoryCodingKey: String { + return "behaviorName" + } + + static var categoryName: String { + return "\(PageBehaviorProtocol.self)" + } +} + +public protocol PageVisibilityBehavior: PageBehaviorProtocol { + + func onPageShown() + func onPageHidden() + +} + +public protocol PageBehaviorsTemplateProtocol { + + var behaviors: [PageBehaviorProtocol]? { get } + +} diff --git a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift new file mode 100644 index 00000000..422222b6 --- /dev/null +++ b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift @@ -0,0 +1,70 @@ +// +// ScreenBrightnessModifierBehavior.swift +// MVMCoreUI +// +// Created by Kyle on 5/9/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { + + static var identifier = "screenBrightnessModifier" + + @Clamping(range: 0...1) var screenBrightness: CGFloat + + var originalScreenBrightness: CGFloat? + + //MARK:- PageVisibilityBehavior + + func onPageShown() { + changeScreenBrightness() + } + + func onPageHidden() { + restoreScreenBrightness() + } + + //MARK:- Behavior + + func changeScreenBrightness() { + if originalScreenBrightness == nil { + originalScreenBrightness = UIScreen.main.brightness + UIScreen.main.brightness = screenBrightness + NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackground), name: UIApplication.willResignActiveNotification, object: nil) + } + } + + func restoreScreenBrightness() { + if let originalScreenBrightness = originalScreenBrightness { + UIScreen.main.brightness = originalScreenBrightness + self.originalScreenBrightness = nil + NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil) + } + } + + @objc func didEnterBackground() { + restoreScreenBrightness() + NotificationCenter.default.addObserver(self, selector: #selector(didEnterForeground), name: UIApplication.didBecomeActiveNotification, object: nil) + } + + @objc func didEnterForeground() { + NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) + changeScreenBrightness() + } + + //MARK:- Codable + + enum CodingKeys: String, CodingKey { + case screenBrightness + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + screenBrightness = try typeContainer.decode(CGFloat.self, forKey: .screenBrightness) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(screenBrightness, forKey: .screenBrightness) + } +} From a19003f240194a90358ee11ed6952ff4fd86c269 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 11 May 2020 12:04:06 -0400 Subject: [PATCH 02/67] privatize coding keys --- MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift index 422222b6..b6712354 100644 --- a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift +++ b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift @@ -54,7 +54,7 @@ class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { //MARK:- Codable - enum CodingKeys: String, CodingKey { + private enum CodingKeys: String, CodingKey { case screenBrightness } From b83abf673ec686865c2aae9ed8f89e6f9dce2253 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 11:17:09 -0400 Subject: [PATCH 03/67] color and indicator inversion --- .../CarouselIndicator/BarsIndicatorView.swift | 18 +++++++++++------- .../CarouselIndicator/CarouselIndicator.swift | 18 +++++++++++++++--- .../CarouselIndicatorModel.swift | 8 ++++++++ MVMCoreUI/Categories/UIColor+Extension.swift | 8 ++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift index 972ea7ca..9dc4a0bd 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift @@ -68,12 +68,7 @@ open class BarsIndicatorView: CarouselIndicator { get { return super.indicatorColor } set (newColor) { super.indicatorColor = newColor - - if isEnabled { - for (i, barTuple) in barReferences.enumerated() { - barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : newColor - } - } + refreshBarColors(with: newColor) } } @@ -102,6 +97,15 @@ open class BarsIndicatorView: CarouselIndicator { // MARK: - Methods //-------------------------------------------------- + private func refreshBarColors(with color: UIColor) { + + if isEnabled { + for (i, barTuple) in barReferences.enumerated() { + barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : color + } + } + } + func generateBars() { var bars = [(View, NSLayoutConstraint)]() @@ -142,7 +146,7 @@ open class BarsIndicatorView: CarouselIndicator { guard let model = model as? BarsCarouselIndicatorModel else { return } - currentIndicatorColor = model.currentIndicatorColor.uiColor + currentIndicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.currentIndicatorColor.uiColor } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift index 9380e8c0..e202a212 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift @@ -78,8 +78,20 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { } public var indicatorColor: UIColor { - get { return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack } - set { carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) } + get { + if let model = carouselIndicatorModel, model.inverted { + return carouselIndicatorModel?.indicatorColor_inverted.uiColor ?? .mvmWhite + } else { + return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack + } + } + set { + if let model = carouselIndicatorModel, model.inverted { + carouselIndicatorModel?.indicatorColor_inverted = Color(uiColor: newValue) + } else { + carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) + } + } } var accessibilityValueFormat: String? { @@ -191,7 +203,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { guard let model = model as? CarouselIndicatorModel else { return } - indicatorColor = model.indicatorColor.uiColor + indicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor disabledIndicatorColor = model.disabledIndicatorColor.uiColor currentIndex = model.currentIndex isEnabled = model.enabled diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index a0ac2273..359fe98a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -26,11 +26,13 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro public var currentIndex: Int = 0 public var animated: Bool = true public var hidesForSinglePage: Bool = false + public var inverted: Bool = false /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false public var accessibilityHasSlidesInsteadOfPage: Bool = false public var enabled: Bool = true public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3) public var indicatorColor: Color = Color(uiColor: .mvmBlack) + public var indicatorColor_inverted: Color = Color(uiColor: .mvmWhite) public var position: Float? /// Allows sendActions() to trigger even if index is already at min/max index. @@ -53,6 +55,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro case disabledIndicatorColor case indicatorColor case position + case inverted } //-------------------------------------------------- @@ -72,6 +75,10 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro self.alwaysSendAction = alwaysSendAction } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + if let position = try typeContainer.decodeIfPresent(Float.self, forKey: .position) { self.position = position } @@ -112,6 +119,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro try container.encode(hidesForSinglePage, forKey: .hidesForSinglePage) try container.encode(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage) try container.encode(enabled, forKey: .enabled) + try container.encode(inverted, forKey: .inverted) try container.encode(disabledIndicatorColor, forKey: .disabledIndicatorColor) try container.encode(indicatorColor, forKey: .indicatorColor) try container.encodeIfPresent(position, forKey: .position) diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 1ef2e217..2ca287d1 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -34,6 +34,7 @@ extension UIColor { "green33": (.mvmGreen33, "#ABE4BF"), "green66": (.mvmGreen66, "#57C880"), "greenShade2": (.mvmGreenShade2, "#0F5B25"), + "greenInverted": (.mvmGreenInverted, "#00AC3E"), "orange": (.mvmOrange, "#ED7000"), "orange66": (.mvmOrange66, "#F3A157"), "orange33": (.mvmOrange33, "#F9D0AB"), @@ -45,6 +46,7 @@ extension UIColor { "blue66": (.mvmBlue66, "#57B1DF"), "blueShade1": (.mvmBlueShade1, "#136598"), "blueShade2": (.mvmBlueShade2, "#0B4467"), + "blueInverted": (.mvmBlueInverted, "#0088CE"), "yellow": (.mvmYellow, "#FFBC3D"), "coolGray1": (.mvmCoolGray1, "#F6F6F6"), "coolGray3": (.mvmCoolGray3, "#D8DADA"), @@ -147,6 +149,9 @@ extension UIColor { /// HEX: #0F5B25 public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37) + /// HEX: #00AC3E + public static let mvmGreenInverted = UIColor.color8Bits(red: 0, green: 172, blue: 62) + //-------------------------------------------------- // MARK: - Blue //-------------------------------------------------- @@ -166,6 +171,9 @@ extension UIColor { /// HEX: #0B4467 public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103) + /// HEX: #0088CE + public static let mvmBlueInverted = UIColor.color8Bits(red: 0, green: 136, blue: 206) + //-------------------------------------------------- // MARK: - Yellow //-------------------------------------------------- From 1a2d7b2abd3b45b2e4f8e2e6a50bf551279fb83f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 11:50:47 -0400 Subject: [PATCH 04/67] arrow color inversion --- MVMCoreUI/Atomic/Atoms/Views/Arrow.swift | 16 ++++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift index ea5023c8..0a3e0457 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift @@ -41,8 +41,20 @@ open class Arrow: View { } open var color: UIColor { - get { return arrowModel?.color.uiColor ?? .mvmBlack } - set { arrowModel?.color = Color(uiColor: newValue) } + get { + if let model = arrowModel, model.inverted { + return arrowModel?.color_inverted.uiColor ?? .mvmWhite + } else { + return arrowModel?.color.uiColor ?? .mvmBlack + } + } + set { + if let model = arrowModel, model.inverted { + arrowModel?.color_inverted = Color(uiColor: newValue) + } else { + arrowModel?.color = Color(uiColor: newValue) + } + } } open var degrees: Float { diff --git a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift index ac2b2d90..35dbd906 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift @@ -22,11 +22,13 @@ open class ArrowModel: MoleculeModelProtocol { public var backgroundColor: Color? public var disabledColor: Color = Color(uiColor: .mvmCoolGray3) public var color: Color = Color(uiColor: .mvmBlack) + public var color_inverted: Color = Color(uiColor: .mvmWhite) public var degrees: Float = 0 public var lineWidth: CGFloat = 1 public var height: CGFloat = 12 public var width: CGFloat = 12 public var enabled: Bool = true + public var inverted: Bool = false //-------------------------------------------------- // MARK: - Enum @@ -64,6 +66,7 @@ open class ArrowModel: MoleculeModelProtocol { case height case width case enabled + case inverted } //-------------------------------------------------- @@ -79,6 +82,10 @@ open class ArrowModel: MoleculeModelProtocol { self.disabledColor = disabledColor } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { self.color = color } From a093d4ec74774cd2fdee1f6929059463363fe82b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 12:45:53 -0400 Subject: [PATCH 05/67] caret view inversion start --- MVMCoreUI/Atomic/Atoms/Views/CaretView.swift | 25 +++++++++--------- .../Atomic/Atoms/Views/CaretViewModel.swift | 26 +++++++++++++++++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift index 93874287..86e8321c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift @@ -13,14 +13,14 @@ open class CaretView: View { //------------------------------------------------------ private var caretPath: UIBezierPath = UIBezierPath() - public var strokeColor: UIColor = .black + public var strokeColor: UIColor = .mvmBlack public var lineWidth: CGFloat = 1 public var direction: Direction = .right public var size: CaretSize? - public var enabledColor: UIColor = .black - public var disabledColor: UIColor = .mfSilver() + public var enabledColor: UIColor = .mvmBlack + public var disabledColor: UIColor = .mvmCoolGray3 //------------------------------------------------------ // MARK: - Property Observer @@ -161,7 +161,7 @@ open class CaretView: View { isOpaque = false isHidden = false backgroundColor = .clear - strokeColor = .black + strokeColor = .mvmBlack } /// Ensure you have defined a CaretSize with Orientation before calling. @@ -177,7 +177,7 @@ open class CaretView: View { // MARK: - Atomization //------------------------------------------------------ - // Default values for view. + /// Default values for view. public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.init(frame: .zero) defaultState() @@ -186,20 +186,21 @@ open class CaretView: View { override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let caretModel = model as? CaretViewModel else { - return - } - strokeColor = caretModel.strokeColor.uiColor - isHidden = caretModel.isHidden ?? false - isOpaque = caretModel.isOpaque ?? false + + guard let model = model as? CaretViewModel else { return } + + strokeColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor + isHidden = model.isHidden ?? false + isOpaque = model.isOpaque ?? false - if let lineWidthValue = caretModel.lineWidth { + if let lineWidthValue = model.lineWidth { lineWidth = lineWidthValue } } } extension CaretView: MVMCoreUIViewConstrainingProtocol { + open func needsToBeConstrained() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index cf90496f..5bcfe092 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -8,15 +8,25 @@ import Foundation -@objcMembers public class CaretViewModel: MoleculeModelProtocol { +@objcMembers public class CaretViewModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "caretView" public var backgroundColor: Color? - public var strokeColor: Color = Color(uiColor: .black) + public var strokeColor: Color = Color(uiColor: .mvmBlack) + public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) public var isHidden: Bool? public var isOpaque: Bool? + public var inverted: Bool = false public var lineWidth: CGFloat? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor @@ -24,13 +34,24 @@ import Foundation case isHidden case isOpaque case lineWidth + case inverted } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) { self.strokeColor = strokeColor } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) @@ -41,6 +62,7 @@ import Foundation var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) + try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(isHidden, forKey: .isHidden) try container.encodeIfPresent(isOpaque, forKey: .isOpaque) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) From b4f8e4281759dedb60e62f2bc62c44128baf491d Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Tue, 12 May 2020 16:06:22 -0400 Subject: [PATCH 06/67] code review items --- .../ScreenBrightnessModifierBehavior.swift | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift index b6712354..03464841 100644 --- a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift +++ b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift @@ -6,9 +6,9 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { +public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { - static var identifier = "screenBrightnessModifier" + public static var identifier = "screenBrightnessModifier" @Clamping(range: 0...1) var screenBrightness: CGFloat @@ -16,38 +16,36 @@ class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { //MARK:- PageVisibilityBehavior - func onPageShown() { + public func onPageShown() { changeScreenBrightness() } - func onPageHidden() { + public func onPageHidden() { restoreScreenBrightness() } //MARK:- Behavior func changeScreenBrightness() { - if originalScreenBrightness == nil { - originalScreenBrightness = UIScreen.main.brightness - UIScreen.main.brightness = screenBrightness - NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackground), name: UIApplication.willResignActiveNotification, object: nil) - } + if originalScreenBrightness != nil { return } + originalScreenBrightness = UIScreen.main.brightness + UIScreen.main.brightness = screenBrightness + NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil) } func restoreScreenBrightness() { - if let originalScreenBrightness = originalScreenBrightness { - UIScreen.main.brightness = originalScreenBrightness - self.originalScreenBrightness = nil - NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil) - } + guard let originalScreenBrightness = originalScreenBrightness else { return } + UIScreen.main.brightness = originalScreenBrightness + self.originalScreenBrightness = nil + NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil) } - @objc func didEnterBackground() { + @objc func willResignActive() { restoreScreenBrightness() - NotificationCenter.default.addObserver(self, selector: #selector(didEnterForeground), name: UIApplication.didBecomeActiveNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) } - @objc func didEnterForeground() { + @objc func didBecomeActive() { NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) changeScreenBrightness() } From 233a0ae71b1b3883a6aff494a345bd5ba00b8a52 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Tue, 12 May 2020 16:07:03 -0400 Subject: [PATCH 07/67] code review --- .../Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index f34c4ebd..3ed37d6b 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, PageBehaviorsTemplateProtocol { +public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol { var template: String { get } } From 5996f26ae193b5447a1a9c4d3657aed8f13f8aa8 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Tue, 12 May 2020 17:45:17 -0400 Subject: [PATCH 08/67] code review --- MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift index 03464841..b6ea9f6d 100644 --- a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift +++ b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift @@ -27,7 +27,7 @@ public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { //MARK:- Behavior func changeScreenBrightness() { - if originalScreenBrightness != nil { return } + guard originalScreenBrightness == nil else { return } originalScreenBrightness = UIScreen.main.brightness UIScreen.main.brightness = screenBrightness NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil) From e676d78eb2294d9b88ec6f580656791fc9d0bb14 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 11:19:13 -0400 Subject: [PATCH 09/67] current state --- MVMCoreUI/Atomic/Atoms/Views/CaretView.swift | 26 +++++++++---------- .../Atomic/Atoms/Views/CaretViewModel.swift | 21 ++++++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift index 86e8321c..20023091 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift @@ -13,7 +13,6 @@ open class CaretView: View { //------------------------------------------------------ private var caretPath: UIBezierPath = UIBezierPath() - public var strokeColor: UIColor = .mvmBlack public var lineWidth: CGFloat = 1 public var direction: Direction = .right @@ -28,7 +27,7 @@ open class CaretView: View { public var isEnabled: Bool = true { didSet { - strokeColor = isEnabled ? enabledColor : disabledColor + guard isEnabled != oldValue else { return } setNeedsDisplay() } } @@ -49,7 +48,7 @@ open class CaretView: View { case horizontal } - // Dimensions of container; provided by InVision design. + /// Dimensions of container; provided by InVision design. func dimensions() -> CGSize { switch self { @@ -92,7 +91,7 @@ open class CaretView: View { //------------------------------------------------------ @objc override open func setupView() { - + super.setupView() defaultState() } @@ -141,7 +140,7 @@ open class CaretView: View { caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: frame.size.height - inset)) } - strokeColor.setStroke() + enabledColor.setStroke() caretPath.stroke() } @@ -151,17 +150,16 @@ open class CaretView: View { @objc public func setLineColor(_ color: UIColor) { - strokeColor = color + enabledColor = color setNeedsDisplay() } @objc public func defaultState() { - translatesAutoresizingMaskIntoConstraints = false isOpaque = false isHidden = false backgroundColor = .clear - strokeColor = .mvmBlack + enabledColor = .mvmBlack } /// Ensure you have defined a CaretSize with Orientation before calling. @@ -178,7 +176,7 @@ open class CaretView: View { //------------------------------------------------------ /// Default values for view. - public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.init(frame: .zero) defaultState() set(with: model, delegateObject, additionalData) @@ -189,12 +187,12 @@ open class CaretView: View { guard let model = model as? CaretViewModel else { return } - strokeColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor - isHidden = model.isHidden ?? false - isOpaque = model.isOpaque ?? false - + enabledColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor + isHidden = model.isHidden + isOpaque = model.isOpaque + if let lineWidthValue = model.lineWidth { - lineWidth = lineWidthValue + lineWidth = lineWidthValue } } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index 5bcfe092..9dc43286 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -18,8 +18,8 @@ import Foundation public var backgroundColor: Color? public var strokeColor: Color = Color(uiColor: .mvmBlack) public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) - public var isHidden: Bool? - public var isOpaque: Bool? + public var isHidden: Bool = false + public var isOpaque: Bool = false public var inverted: Bool = false public var lineWidth: CGFloat? @@ -31,6 +31,7 @@ import Foundation case moleculeName case backgroundColor case strokeColor + case strokeColor_inverted case isHidden case isOpaque case lineWidth @@ -48,13 +49,24 @@ import Foundation self.strokeColor = strokeColor } + if let strokeColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor_inverted) { + self.strokeColor_inverted = strokeColor_inverted + } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { self.inverted = inverted } backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) - isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) + + if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) { + self.isHidden = isHidden + } + + if let isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) { + self.isOpaque = isOpaque + } + lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth) } @@ -62,6 +74,7 @@ import Foundation var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) + try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted) try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(isHidden, forKey: .isHidden) try container.encodeIfPresent(isOpaque, forKey: .isOpaque) From 7b2d684c4e7c086481d3214e77da5d24f048e6d1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 14:25:45 -0400 Subject: [PATCH 10/67] changes for inversion --- .../Atomic/Atoms/Buttons/CaretLink.swift | 11 ++-- .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 44 ++++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 50 +++++++++++++------ 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift index d23a2606..0e2dfd7b 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift @@ -9,14 +9,13 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { - //------------------------------------------------------ // MARK: - Constants //------------------------------------------------------ private let CARET_VIEW_HEIGHT: Float = 10.5 private let CARET_VIEW_WIDTH: Float = 6.5 - + //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------ @@ -82,7 +81,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { setTitleColor(enabledColor, for: .normal) setTitleColor(disabledColor, for: .disabled) - + if let rightCaretView = rightView as? CaretView { rightCaretView.enabledColor = enabledColor rightCaretView.disabledColor = disabledColor @@ -123,7 +122,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { bottomAnchor.constraint(greaterThanOrEqualTo: caretView.bottomAnchor).isActive = true contentHorizontalAlignment = .left - //set correct color after layout + // Set correct color after layout changeCaretColor() } @@ -135,6 +134,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Atomization //------------------------------------------------------ + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? CaretLinkModel else { return } @@ -143,7 +143,8 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { backgroundColor = color.uiColor } - enabledColor = model.enabledColor.uiColor + enabledColor = (model.inverted ? model.enabled_inverted : model.enabledColor).uiColor + if let color = model.disabledColor { disabledColor = color.uiColor } diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 8f3ee74d..5b48deea 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -9,46 +9,80 @@ import Foundation import MVMCore + public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "caretLink" public var backgroundColor: Color? public var title: String public var action: ActionModelProtocol - public var enabledColor: Color = Color(uiColor: .black) + public var enabledColor: Color = Color(uiColor: .mvmBlack) public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6) + public var enabled_inverted: Color = Color(uiColor: .mvmWhite) public var enabled = true - + public var inverted = false + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(title: String, action: ActionModelProtocol) { self.title = title self.action = action } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case backgroundColor case title case action + case enabled_inverted case enabledColor case disabledColor case enabled + case inverted case moleculeName } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) + + if let enabled_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabled_inverted) { + self.enabled_inverted = enabled_inverted + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { enabledColor = color } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { disabledColor = color } + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { self.enabled = enabled } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + action = try typeContainer.decodeModel(codingKey: .action) } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) @@ -58,5 +92,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(enabled, forKey: .enabledColor) try container.encodeIfPresent(disabledColor, forKey: .disabledColor) try container.encode(enabled, forKey: .enabled) + try container.encode(enabled_inverted, forKey: .enabled_inverted) + try container.encode(inverted, forKey: .inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 7412230d..dbd1727e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -9,13 +9,16 @@ import UIKit @objcMembers public class LineModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- - /* - The frequency of the line in a moleculeList. - all (between all cells, above top, below bottom) - allExceptTop (between all cells, below bottom) - allExceptBottom (between all cells, above top) - between (between all cells) + /** + The frequency of the line in a moleculeList: + - all (between all cells, above top, below bottom) + - allExceptTop (between all cells, below bottom) + - allExceptBottom (between all cells, above top) + - between (between all cells) */ public enum Frequency: String, Codable { case all @@ -24,13 +27,13 @@ import UIKit case between } - /* - The style of the line. - standard (1 height, silver) - thin (1 height, black) - medium (2 height, black) - heavy (4 height, black) - none (hidden) + /** + The style of the line: + - standard (1 height, silver) + - thin (1 height, black) + - medium (2 height, black) + - heavy (4 height, black) + - none (hidden) */ public enum Style: String, Codable { case standard @@ -40,23 +43,35 @@ import UIKit case none } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "line" public var type: Style = .standard public var frequency: Frequency? = .allExceptTop //TODO: use color insted of backgroundColor. Needs server changes -// public var color: Color? + // public var color: Color? public var backgroundColor: Color? // Use this to show vertical line // Default is false public var useVerticalLine: Bool? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(type: Style) { self.type = type self.useVerticalLine = false } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case type @@ -66,14 +81,21 @@ import UIKit case useVerticalLine } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) { self.type = type } + if let frequency = try typeContainer.decodeIfPresent(Frequency.self, forKey: .frequency) { self.frequency = frequency } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine) } From 59288c8fdf934988cd4eb6a81aa480563c910e28 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 17:12:51 -0400 Subject: [PATCH 11/67] latest inversion --- MVMCoreUI/Atomic/Atoms/Views/DashLine.swift | 28 +++++------ .../Atomic/Atoms/Views/DashLineModel.swift | 36 ++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/Line.swift | 46 ++++++++++++++---- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 47 ++++++++++++------- 4 files changed, 114 insertions(+), 43 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift index 86d2fd61..c8a59c6d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift @@ -18,10 +18,10 @@ open class DashLine: View { var dashModel: DashLineModel? { get { return model as? DashLineModel } } - + //TODO: Need this for BAU. Can remove once we fix BAU public var dashColor: UIColor? - + @objc private var dashLayer: CAShapeLayer? //------------------------------------------------------ @@ -65,15 +65,15 @@ open class DashLine: View { path.addLine(to: CGPoint(x: dashLayer.frame.size.width, y: 0)) path.stroke() - dashLayer.strokeStart = 0.0 + dashLayer.strokeStart = 0 dashLayer.lineWidth = 1 dashLayer.lineJoin = .miter dashLayer.lineCap = .round dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)] dashLayer.path = path.cgPath - dashLayer.strokeColor = dashModel?.dashColor.cgColor ?? dashColor?.cgColor + dashLayer.strokeColor = dashColor?.cgColor dashLayer.fillColor = UIColor.clear.cgColor - dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor + dashLayer.backgroundColor = (dashModel?.inverted ?? false) ? UIColor.mvmBlack.cgColor : backgroundColor?.cgColor ?? UIColor.mvmWhite.cgColor self.dashLayer = dashLayer } @@ -81,21 +81,21 @@ open class DashLine: View { // MARK: - Atomization //------------------------------------------------------ - // Default values for view. @objc open override func reset() { - backgroundColor = .clear + super.reset() + isHidden = false } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let dashLineModel = dashModel else { - return - } - if let isHiddenValue = dashLineModel.isHidden { - isHidden = isHiddenValue - } - if let backgroundColor = dashLineModel.backgroundColor { + + guard let model = dashModel else { return } + + isHidden = model.isHidden + dashColor = (model.inverted ? model.dashColor_inverted : model.dashColor).uiColor + + if let backgroundColor = model.backgroundColor { dashLayer?.backgroundColor = backgroundColor.uiColor.cgColor } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift index 7f5ac992..523d83a6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift @@ -8,38 +8,66 @@ import Foundation + @objcMembers public class DashLineModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "dashLine" public var backgroundColor: Color? + public var dashColor: Color = Color(uiColor: .mvmCoolGray3) + public var dashColor_inverted: Color = Color(uiColor: .mvmWhite) + public var isHidden: Bool = false + public var inverted: Bool = false - public var dashColor: Color = Color(uiColor: .mfLighterGray()) - public var isHidden: Bool? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- public init(dashColor: Color) { self.dashColor = dashColor } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor + case dashColor_inverted case dashColor case isHidden } + + //-------------------------------------------------- + // MARK: - codec + //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let dashColor = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor) { self.dashColor = dashColor } + + if let dashColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor_inverted) { + self.dashColor_inverted = dashColor_inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) + + if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) { + self.isHidden = isHidden + } } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(dashColor, forKey: .dashColor) - try container.encodeIfPresent(isHidden, forKey: .isHidden) + try container.encode(isHidden, forKey: .isHidden) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 42043c8f..d0890540 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -8,14 +8,27 @@ import UIKit + @objcMembers open class Line: View { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + var lineModel: LineModel? { get { return model as? LineModel } } + var lineBackgroundColor: Color? { + return (lineModel?.inverted ?? false) ? lineModel?.backgroundColor_inverted : lineModel?.backgroundColor + } + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + public var heightConstraint: NSLayoutConstraint? public var widthConstraint: NSLayoutConstraint? - + open func updateLineConstraints(constant: CGFloat) { if let useVerticalLine = lineModel?.useVerticalLine, useVerticalLine { heightConstraint?.isActive = false @@ -28,7 +41,23 @@ import UIKit } } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + + public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { + self.init(frame: .zero) + + view.addSubview(self) + NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + open func setStyle(_ style: LineModel.Style) { + switch style { case .standard: updateLineConstraints(constant: 1) @@ -47,21 +76,18 @@ import UIKit } } - // MARK: - Helpers open func shouldBeVisible() -> Bool { guard let type = lineModel?.type else { return false } return type != .none } - public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { - self.init(frame: .zero) - view.addSubview(self) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) - } + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol + //-------------------------------------------------- - // MARK: - MVMCoreViewProtocol open override func setupView() { super.setupView() + heightConstraint = heightAnchor.constraint(equalToConstant: 1) heightConstraint?.isActive = true widthConstraint = widthAnchor.constraint(equalToConstant: 1) @@ -69,9 +95,9 @@ import UIKit setStyle(.standard) } - // MARK: - MoleculeViewProtocol open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + if let lineModel = model as? LineModel { setStyle(lineModel.type) } @@ -82,7 +108,9 @@ import UIKit } public override static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let type = (model as? LineModel)?.type else { return 1 } + switch type { case .none: return 0 diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index dbd1727e..8a245066 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -8,18 +8,19 @@ import UIKit + @objcMembers public class LineModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- /** - The frequency of the line in a moleculeList: - - all (between all cells, above top, below bottom) - - allExceptTop (between all cells, below bottom) - - allExceptBottom (between all cells, above top) - - between (between all cells) - */ + The frequency of the line in a moleculeList: + - all (between all cells, above top, below bottom) + - allExceptTop (between all cells, below bottom) + - allExceptBottom (between all cells, above top) + - between (between all cells) + */ public enum Frequency: String, Codable { case all case allExceptTop @@ -28,13 +29,13 @@ import UIKit } /** - The style of the line: - - standard (1 height, silver) - - thin (1 height, black) - - medium (2 height, black) - - heavy (4 height, black) - - none (hidden) - */ + The style of the line: + - standard (1 height, silver) + - thin (1 height, black) + - medium (2 height, black) + - heavy (4 height, black) + - none (hidden) + */ public enum Style: String, Codable { case standard case thin @@ -50,10 +51,12 @@ import UIKit public static var identifier: String = "line" public var type: Style = .standard public var frequency: Frequency? = .allExceptTop - + //TODO: use color insted of backgroundColor. Needs server changes // public var color: Color? public var backgroundColor: Color? + public var backgroundColor_inverted: Color = Color(uiColor: .mvmWhite) + public var inverted: Bool = false // Use this to show vertical line // Default is false @@ -76,15 +79,17 @@ import UIKit case moleculeName case type case backgroundColor + case backgroundColor_inverted case color case frequency + case inverted case useVerticalLine } //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -96,14 +101,24 @@ import UIKit self.frequency = frequency } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + + if let backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted) { + + self.backgroundColor_inverted = backgroundColor_inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine) } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(type, forKey: .type) + try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine) From e9a9c953736f12daf45a13978caaca97a5f6c4b2 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 14 May 2020 15:02:19 -0400 Subject: [PATCH 12/67] inversion colors --- .../Atoms/Buttons/Link/ExternalLink.swift | 2 +- .../Buttons/Link/ExternalLinkModel.swift | 1 + .../Atomic/Atoms/Buttons/Link/Link.swift | 16 ++- .../Atomic/Atoms/Buttons/Link/LinkModel.swift | 32 ++++- .../Atomic/Atoms/Selectors/Checkbox.swift | 42 +++--- .../Atoms/Selectors/CheckboxModel.swift | 130 +++++++++++++----- .../RadioButtonLabel.swift | 5 +- .../RadioButtonLabelModel.swift | 5 + 8 files changed, 166 insertions(+), 67 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift index c65698c3..e051cf32 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift @@ -25,7 +25,7 @@ open class ExternalLink: Link { guard let model = model as? ExternalLinkModel else { return } - exportImageView?.tintColor = model.enabledColor.uiColor + exportImageView?.tintColor = titleColor(for: model.enabled ? .normal : .disabled) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift index f492a546..19d6643c 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift @@ -8,6 +8,7 @@ import UIKit + open class ExternalLinkModel: LinkModel { override open class var identifier: String { diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift index 5f5e6e12..7413fcbb 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift @@ -37,9 +37,7 @@ import UIKit } open override var intrinsicContentSize: CGSize { - guard let size = titleLabel?.intrinsicContentSize else { - return super.intrinsicContentSize - } + guard let size = titleLabel?.intrinsicContentSize else { return super.intrinsicContentSize } return CGSize(width: size.width, height: size.height + 2) } @@ -49,17 +47,18 @@ import UIKit public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + guard let model = model as? LinkModel else { return } setTitle(model.title, for: .normal) - setTitleColor(model.enabledColor.uiColor, for: .normal) - setTitleColor(model.disabledColor.uiColor, for: .disabled) + setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal) + setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled) isEnabled = model.enabled set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 31.0 + return 31 } } @@ -68,12 +67,15 @@ extension Link { open override func updateView(_ size: CGFloat) { super.updateView(size) + DispatchQueue.main.async { [weak self] in guard let self = self else { return } + var width = size - if MVMCoreGetterUtility.fequal(a: Float(CGFloat.leastNormalMagnitude), b: Float(size)) { + if MVMCoreGetterUtility.fequal(a: Float.leastNormalMagnitude, b: Float(size)) { width = MVMCoreUIUtility.getWidth() } + self.titleLabel?.font = MFStyler.fontB2(forWidth: width) } } diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index a54f23e9..d51bddf4 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -8,6 +8,7 @@ import UIKit + open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties @@ -22,7 +23,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { public var action: ActionModelProtocol public var enabled = true public var enabledColor = Color(uiColor: .mvmBlack) + public var enabledColor_inverted = Color(uiColor: .mvmWhite) public var disabledColor = Color(uiColor: .mvmCoolGray6) + public var disabledColor_inverted = Color(uiColor: .mvmCoolGray10) + public var inverted = false //-------------------------------------------------- // MARK: - Initializer @@ -44,7 +48,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { case action case enabled case enabledColor + case enabledColor_inverted case disabledColor + case disabledColor_inverted + case inverted } //-------------------------------------------------- @@ -53,6 +60,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action) @@ -60,12 +68,25 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { self.enabled = enabled } - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { - enabledColor = color + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted } - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { - disabledColor = color + if let enabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { + self.enabledColor = enabledColor + } + + if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) { + self.enabledColor_inverted = enabledColor_inverted + } + + if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { + self.disabledColor = disabledColor + } + + if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) { + self.disabledColor_inverted = disabledColor_inverted } } @@ -75,8 +96,11 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModel(action, forKey: .action) + try container.encode(inverted, forKey: .inverted) try container.encode(enabled, forKey: .enabled) try container.encode(enabledColor, forKey: .enabledColor) + try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted) try container.encode(disabledColor, forKey: .disabledColor) + try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift index cb404f5a..cffbb916 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift @@ -97,7 +97,7 @@ import MVMCore public var disabledCheckColor: UIColor = .mvmCoolGray3 /// Color of the check mark. - public var checkColor: UIColor = .black { + public var checkColor: UIColor = .mvmBlack { didSet { setShapeLayerStrokeColor(checkColor) } @@ -111,7 +111,7 @@ import MVMCore } /// border color of the Checkbox - public var borderColor: UIColor = .black { + public var borderColor: UIColor = .mvmBlack { didSet { layer.borderColor = borderColor.cgColor } @@ -126,7 +126,7 @@ import MVMCore didSet { if !updateSelectionOnly { layoutIfNeeded() - (model as? CheckboxModel)?.isChecked = isSelected + (model as? CheckboxModel)?.checked = isSelected shapeLayer?.removeAllAnimations() updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated) _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) @@ -375,10 +375,10 @@ import MVMCore shapeLayer?.removeFromSuperlayer() shapeLayer = nil backgroundColor = .clear - borderColor = .black - borderWidth = 1.0 - checkColor = .black - checkWidth = 2.0 + borderColor = .mvmBlack + borderWidth = 1 + checkColor = .mvmBlack + checkWidth = 2 checkAndBypassAnimations(selected: false) } @@ -393,32 +393,34 @@ import MVMCore public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? CheckboxModel else { return } self.delegateObject = delegateObject + + guard let model = model as? CheckboxModel else { return } + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) if let fieldKey = model.fieldKey { self.fieldKey = fieldKey } - borderColor = model.borderColor.uiColor + borderColor = (model.inverted ? model.invertedColor : model.borderColor).uiColor borderWidth = model.borderWidth - checkColor = model.checkColor.uiColor - unCheckedBackgroundColor = model.unCheckedBackgroundColor.uiColor - checkedBackgroundColor = model.checkedBackgroundColor.uiColor - disabledCheckColor = model.disabledCheckColor.uiColor - disabledBorderColor = model.disabledBorderColor.uiColor - disabledBackgroundColor = model.disabledBackgroundColor.uiColor + checkColor = (model.inverted ? model.invertedColor : model.checkColor).uiColor + unCheckedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.unCheckedBackgroundColor).uiColor + checkedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.checkedBackgroundColor).uiColor + disabledCheckColor = (model.inverted ? model.invertedColor : model.disabledCheckColor).uiColor + disabledBorderColor = (model.inverted ? model.invertedColor : model.disabledBorderColor).uiColor + disabledBackgroundColor = (model.inverted ? model.invertedColor : model.disabledBackgroundColor).uiColor - isAnimated = model.isAnimated - isRound = model.isRound + isAnimated = model.animated + isRound = model.round - if model.isChecked { - checkAndBypassAnimations(selected: model.isChecked) + if model.checked { + checkAndBypassAnimations(selected: model.checked) } - isEnabled = model.isEnabled + isEnabled = model.enabled if let action = model.action { actionBlock = { diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 423ed1ee..43a08aa6 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -8,6 +8,7 @@ import Foundation + @objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- // MARK: - Properties @@ -15,20 +16,23 @@ import Foundation public static var identifier: String = "checkbox" public var backgroundColor: Color? - public var isChecked: Bool = false - public var isEnabled: Bool = true - public var isAnimated: Bool = true - public var isRound: Bool = false + public var checked: Bool = false + public var enabled: Bool = true + public var animated: Bool = true + public var inverted: Bool = false + public var round: Bool = false public var borderWidth: CGFloat = 1 - public var borderColor: Color = Color(uiColor: .black) - public var checkColor: Color = Color(uiColor: .black) + public var borderColor: Color = Color(uiColor: .mvmBlack) + public var checkColor: Color = Color(uiColor: .mvmBlack) public var unCheckedBackgroundColor: Color = Color(uiColor: .clear) public var checkedBackgroundColor: Color = Color(uiColor: .clear) public var disabledBackgroundColor: Color = Color(uiColor: .clear) public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3) public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3) + public var invertedColor: Color = Color(uiColor: .mvmWhite) + public var invertedBackgroundColor: Color = Color(uiColor: .mvmBlack) public var action: ActionModelProtocol? - + public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? @@ -39,13 +43,16 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName - case isChecked = "checked" - case isEnabled = "enabled" - case isAnimated = "animated" - case isRound = "round" + case checked + case enabled + case inverted + case animated + case round case borderWidth case borderColor case checkColor + case invertedColor + case invertedBackgroundColor case unCheckedBackgroundColor case checkedBackgroundColor case disabledBackgroundColor @@ -56,12 +63,20 @@ import Foundation case groupName } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public func formFieldValue() -> AnyHashable? { - return isChecked + return checked } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(isChecked: Bool = false) { - self.isChecked = isChecked + self.checked = isChecked baseValue = isChecked } @@ -71,22 +86,72 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1 - borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black) - checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black) - unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) ?? Color(uiColor: .clear) - checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) ?? Color(uiColor: .clear) - disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) ?? Color(uiColor: .clear) - disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) ?? Color(uiColor: .mvmCoolGray3) - disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) ?? Color(uiColor: .mvmCoolGray3) - isChecked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isChecked) ?? false - isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true - isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false - isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true - action = try typeContainer.decodeModelIfPresent(codingKey: .action) - baseValue = isChecked + if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { + self.borderWidth = borderWidth + } + + if let borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) { + self.borderColor = borderColor + } + + if let checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) { + self.checkColor = checkColor + } + + if let unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) { + self.unCheckedBackgroundColor = unCheckedBackgroundColor + } + + if let checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) { + self.checkedBackgroundColor = checkedBackgroundColor + } + + if let disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) { + self.disabledBackgroundColor = disabledBackgroundColor + } + + if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) { + self.disabledBorderColor = disabledBorderColor + } + + if let disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) { + self.disabledCheckColor = disabledCheckColor + } + + if let invertedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedColor) { + self.invertedColor = invertedColor + } + + if let invertedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedBackgroundColor) { + self.invertedBackgroundColor = invertedBackgroundColor + } + + if let checked = try typeContainer.decodeIfPresent(Bool.self, forKey: .checked) { + self.checked = checked + } + + baseValue = checked + + if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) { + self.animated = animated + } + + if let round = try typeContainer.decodeIfPresent(Bool.self, forKey: .round) { + self.round = round + } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } + + action = try typeContainer.decodeModelIfPresent(codingKey: .action) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { self.groupName = groupName } @@ -99,16 +164,19 @@ import Foundation try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(borderColor, forKey: .borderColor) try container.encode(borderWidth, forKey: .borderWidth) - try container.encode(isChecked, forKey: .isChecked) + try container.encode(checked, forKey: .checked) + try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(checkColor, forKey: .checkColor) + try container.encodeIfPresent(invertedColor, forKey: .invertedColor) + try container.encodeIfPresent(invertedBackgroundColor, forKey: .invertedBackgroundColor) try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor) try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor) try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor) try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor) try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor) - try container.encodeIfPresent(isAnimated, forKey: .isAnimated) - try container.encodeIfPresent(isRound, forKey: .isRound) - try container.encodeIfPresent(isEnabled, forKey: .isEnabled) + try container.encodeIfPresent(animated, forKey: .animated) + try container.encodeIfPresent(round, forKey: .round) + try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeModelIfPresent(action, forKey: .action) try container.encodeIfPresent(groupName, forKey: .groupName) } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift index 91034095..d415971e 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift @@ -8,6 +8,7 @@ import UIKit + @objcMembers public class RadioButtonLabel: View { public let radioButton = RadioButton() @@ -35,9 +36,6 @@ import UIKit open override func setupView() { super.setupView() - guard subviews.count == 0 else { - return - } addSubview(radioButton) radioButton.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor, constant: 0).isActive = true @@ -72,5 +70,4 @@ import UIKit radioButton.set(with: radioButtonLabelModel.radioButton, delegateObject, additionalData) label.set(with: radioButtonLabelModel.label, delegateObject, additionalData) } - } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index 62df9794..014030ce 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -8,7 +8,12 @@ import Foundation + @objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "radioButtonLabel" public var backgroundColor: Color? public var moleculeName: String From ac86d925744f00116021e0c511227781cf1fb8ba Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 09:03:57 -0400 Subject: [PATCH 13/67] No Validate on Emoty --- .../Atomic/Atoms/TextFields/TextEntryField.swift | 2 ++ .../Atoms/TextFields/TextViewEntryField.swift | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 9d7c8927..41254355 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -259,6 +259,7 @@ import UIKit observingTextFieldDelegate?.isInvalid?(textfield: self) } } + /// Executes on UITextField.textDidBeginEditingNotification @objc func startEditing() { isSelected = true @@ -278,6 +279,7 @@ import UIKit // Don't show error till user starts typing. guard text?.count ?? 0 != 0 else { + showError = false return } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index 546b5c30..35e25075 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -71,7 +71,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele /// The text of this textView. open override var text: String? { - get { return textView.text } + get { return textViewEntryFieldModel?.text } set { textView.text = newValue textViewEntryFieldModel?.text = newValue @@ -207,8 +207,19 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele /// Executes on UITextView.textDidEndEditingNotification @objc func endInputing() { - resignFirstResponder() isSelected = false + resignFirstResponder() + + // Don't show error till user starts typing. + guard text?.count ?? 0 != 0 else { + showError = false + return + } + + if let isValid = (model as? TextEntryFieldModel)?.isValid { + self.isValid = isValid + } + showError = !isValid } From 868836b96312a52720aabd7ea3ee0d0df314b705 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 09:10:16 -0400 Subject: [PATCH 14/67] changes to prevent validation on no text. --- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 3 ++- MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 41254355..5b131fe6 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -283,9 +283,10 @@ import UIKit return } - if let isValid = (model as? TextEntryFieldModel)?.isValid { + if let isValid = textEntryFieldModel?.isValid { self.isValid = isValid } + shouldShowError(!isValid) } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index 35e25075..9cbf2c57 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -216,7 +216,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele return } - if let isValid = (model as? TextEntryFieldModel)?.isValid { + if let isValid = textViewEntryFieldModel?.isValid { self.isValid = isValid } From fb7760a329f05d56455d0346dc85210f7ae2ba7c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 10:55:46 -0400 Subject: [PATCH 15/67] moving validator to parent --- .../Atomic/Atoms/TextFields/EntryField.swift | 29 +++++++++++++++++++ .../Atoms/TextFields/TextEntryField.swift | 22 ++++---------- .../Atoms/TextFields/TextViewEntryField.swift | 22 ++++---------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index e54cb80f..3a5084c6 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -49,6 +49,9 @@ import UIKit public var isValid: Bool = false + /// Validate on each entry in the textField. Default: true + public var validateEachCharacter: Bool = true + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -229,6 +232,32 @@ import UIKit entryFieldContainer.updateView(size) } + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + + /// Executes on .textDidBeginEditingNotification + @objc func startEditing() { + isSelected = true + } + + /// Executes on .textDidChangeNotification (each character entry) + @objc func valueChanged() { + guard validateEachCharacter else { return } + } + + /// Executes on .textDidEndEditingNotification + @objc func endInputing() { + isSelected = false + resignFirstResponder() + + // Don't show error till user starts typing. + guard text?.count ?? 0 != 0 else { + showError = false + return + } + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 5b131fe6..969fdfd4 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -51,9 +51,6 @@ import UIKit private var observingForChange: Bool = false - /// Validate on each entry in the textField. Default: true - public var validateEachCharacter: Bool = true - /// Validate when user resigns editing. Default: true public var validateWhenDoneEditing: Bool = true @@ -261,27 +258,20 @@ import UIKit } /// Executes on UITextField.textDidBeginEditingNotification - @objc func startEditing() { - isSelected = true + @objc override func startEditing() { + super.startEditing() textField.becomeFirstResponder() } /// Executes on UITextField.textDidChangeNotification (each character entry) - @objc func valueChanged() { - guard validateEachCharacter else { return } - isSelected = true + @objc override func valueChanged() { + super.valueChanged() validateTextField() } /// Executes on UITextField.textDidEndEditingNotification - @objc func endInputing() { - resignFirstResponder() - - // Don't show error till user starts typing. - guard text?.count ?? 0 != 0 else { - showError = false - return - } + @objc override func endInputing() { + super.endInputing() if let isValid = textEntryFieldModel?.isValid { self.isValid = isValid diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index 9cbf2c57..4331701c 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -24,9 +24,6 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele // MARK: - Properties //-------------------------------------------------- - /// Validate on each entry in the textView. Default: true - public var validateEachCharacter: Bool = true - private var observingForChange: Bool = false //-------------------------------------------------- @@ -194,27 +191,20 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele } /// Executes on UITextView.textDidBeginEditingNotification - @objc func startEditing() { - isSelected = true + @objc override func startEditing() { + super.startEditing() _ = textView.becomeFirstResponder() } /// Executes on UITextView.textDidChangeNotification (each character entry) - @objc func valueChanged() { - guard validateEachCharacter else { return } + @objc override func valueChanged() { + super.valueChanged() validateTextView() } /// Executes on UITextView.textDidEndEditingNotification - @objc func endInputing() { - isSelected = false - resignFirstResponder() - - // Don't show error till user starts typing. - guard text?.count ?? 0 != 0 else { - showError = false - return - } + @objc override func endInputing() { + super.endInputing() if let isValid = textViewEntryFieldModel?.isValid { self.isValid = isValid From ad4dfcf74819e888f98cde848a273c1a011a5cdb Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 12:20:39 -0400 Subject: [PATCH 16/67] further changes to orbservation --- MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift | 6 ------ MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 6 ++++++ MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 3a5084c6..499fe5a8 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -250,12 +250,6 @@ import UIKit @objc func endInputing() { isSelected = false resignFirstResponder() - - // Don't show error till user starts typing. - guard text?.count ?? 0 != 0 else { - showError = false - return - } } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 969fdfd4..63ba9e71 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -272,6 +272,12 @@ import UIKit /// Executes on UITextField.textDidEndEditingNotification @objc override func endInputing() { super.endInputing() + + // Don't show error till user starts typing. + guard text?.count ?? 0 != 0 else { + showError = false + return + } if let isValid = textEntryFieldModel?.isValid { self.isValid = isValid diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index 4331701c..cb8e2cae 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -206,6 +206,12 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele @objc override func endInputing() { super.endInputing() + // Don't show error till user starts typing. + guard text?.count ?? 0 != 0 else { + showError = false + return + } + if let isValid = textViewEntryFieldModel?.isValid { self.isValid = isValid } From 6a9957d34827516d0cda4277989d546c1720ca4a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 13:56:57 -0400 Subject: [PATCH 17/67] moved code to parent --- MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift | 4 ++-- MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift | 7 +++++++ MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 8 ++++---- .../Atomic/Atoms/TextFields/TextViewEntryField.swift | 8 +++----- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 628c7cde..18f61b2d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -322,7 +322,7 @@ import UIKit @objc override open func resignFirstResponder() -> Bool { if validateWhenDoneEditing { - validateTextField() + validateText() } selectedDigitBox?.isSelected = false @@ -440,7 +440,7 @@ extension DigitEntryField { selectedDigitBox = nil if !switchFieldsAutomatically && validateWhenDoneEditing { - validateTextField() + validateText() } proprietorTextDelegate?.textFieldDidEndEditing?(textField) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 499fe5a8..41fec6bb 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -236,6 +236,13 @@ import UIKit // MARK: - Validation //-------------------------------------------------- + /// Validates the text of the entry field. + @objc public func validateText() { + if let isValid = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) { + self.isValid = isValid + } + } + /// Executes on .textDidBeginEditingNotification @objc func startEditing() { isSelected = true diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 63ba9e71..e849fc2f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -223,7 +223,7 @@ import UIKit @discardableResult @objc override open func resignFirstResponder() -> Bool { if validateWhenDoneEditing { - validateTextField() + validateText() } textField.resignFirstResponder() isSelected = false @@ -231,9 +231,9 @@ import UIKit } /// Validates the text of the entry field. - @objc public func validateTextField() { + @objc public override func validateText() { text = textField.text - _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) + super.validateText() } @objc public func updateValidation(_ isValid: Bool) { @@ -266,7 +266,7 @@ import UIKit /// Executes on UITextField.textDidChangeNotification (each character entry) @objc override func valueChanged() { super.valueChanged() - validateTextField() + validateText() } /// Executes on UITextField.textDidEndEditingNotification diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index cb8e2cae..e08f3843 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -183,11 +183,9 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele //-------------------------------------------------- /// Validates the text of the entry field. - @objc public func validateTextView() { + @objc public override func validateText() { text = textView.text - if let isValid = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) { - self.isValid = isValid - } + super.validateText() } /// Executes on UITextView.textDidBeginEditingNotification @@ -199,7 +197,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele /// Executes on UITextView.textDidChangeNotification (each character entry) @objc override func valueChanged() { super.valueChanged() - validateTextView() + validateText() } /// Executes on UITextView.textDidEndEditingNotification From 57342800fe6d60399f98173e60476998532d3b43 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 15 May 2020 23:30:49 +0530 Subject: [PATCH 18/67] image width and height fix 1. making addSizeConstraintsForAspectRatio default true 2. removing 900 priority constraints --- MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift b/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift index e3c9123e..baa63ee8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift @@ -11,7 +11,7 @@ import UIKit @objcMembers open class LoadImageView: View { public let loadingSpinner = MFLoadingSpinner(frame: .zero) public let imageView = MFTransparentGIFView(frame: .zero) - public var addSizeConstraintsForAspectRatio = false + public var addSizeConstraintsForAspectRatio = true public var shouldNotifyDelegateOnUpdate = true var centerX: NSLayoutConstraint? var centerY: NSLayoutConstraint? @@ -173,7 +173,6 @@ import UIKit } else { heightConstraint?.isActive = false heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height) - heightConstraint?.priority = UILayoutPriority(rawValue: 900) } heightConstraint?.isActive = true } @@ -183,7 +182,6 @@ import UIKit widthConstraint.constant = width } else { widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width) - widthConstraint?.priority = UILayoutPriority(rawValue: 900) } widthConstraint?.isActive = true } From 7e3c9fdcdbbbdcd43cc85809d36185d8bbb6b0f1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 15:20:03 -0400 Subject: [PATCH 19/67] new rule equalsignorecase --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../Rules/RuleEqualsIgnoreCaseModel.swift | 55 +++++++++++++++++++ .../Rules/Rules/RuleRequiredModel.swift | 1 + 4 files changed, 61 insertions(+) create mode 100644 MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d7afb970..20472d78 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -92,6 +92,7 @@ 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */; }; 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; + 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */; }; 0A9D091D2433796500D2E6C0 /* BarsCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */; }; 0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */; }; 0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */; }; @@ -505,6 +506,7 @@ 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; + 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsIgnoreCaseModel.swift; sourceTree = ""; }; 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarsCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericIndicatorView.swift; sourceTree = ""; }; @@ -873,6 +875,7 @@ 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */, 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */, + 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */, ); name = Rules; path = Rules/Rules; @@ -2038,6 +2041,7 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */, + 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */, D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */, AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 76c17c6a..0a0768f8 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -194,6 +194,7 @@ import Foundation try? ModelRegistry.register(RuleAnyValueChangedModel.self) try? ModelRegistry.register(RuleAllValueChangedModel.self) try? ModelRegistry.register(RuleEqualsModel.self) + try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self) try? ModelRegistry.register(RuleRegexModel.self) // Actions diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift new file mode 100644 index 00000000..c988cfce --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -0,0 +1,55 @@ +// +// RuleEqualsIgnoreCaseModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 5/15/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public class RuleEqualsIgnoreCaseModel: RulesProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "equalsIgnoreCase" + public var type: String = RuleEqualsModel.identifier + public var fields: [String] + public var errorMessage: [String: String]? + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } + + public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { + var valid = true + var compareValue: AnyHashable? + + for formKey in fields { + guard let formField = fieldMolecules[formKey] else { continue } + + if compareValue == nil { + compareValue = formField.formFieldValue() + continue + } + + let a = compareValue.caseInsensitiveCompare(formField.formFieldValue()) + + if compareValue != formField.formFieldValue() { + valid = false + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) + break + } else { + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) + } + } + + return valid + } +} diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift index c9e7d9f7..77cdf254 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift @@ -24,6 +24,7 @@ public class RuleRequiredModel: RulesProtocol { //-------------------------------------------------- public func isValid(_ formField: FormFieldProtocol) -> Bool { + guard let value = formField.formFieldValue() else { return false } var valid = true From 461fd5e2cab9a58cb7c7fe31e9b3c513a573b169 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 15:37:40 -0400 Subject: [PATCH 20/67] new rule logic. --- .../Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index c988cfce..15bcb3f0 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -28,23 +28,21 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { } public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { - var valid = true - var compareValue: AnyHashable? + var valid = false + var compareValue: String? for formKey in fields { guard let formField = fieldMolecules[formKey] else { continue } if compareValue == nil { - compareValue = formField.formFieldValue() + compareValue = formField.formFieldValue() as? String continue } - - let a = compareValue.caseInsensitiveCompare(formField.formFieldValue()) - if compareValue != formField.formFieldValue() { + if let compareValue = compareValue, let fieldValue = formField.formFieldValue() as? String, + compareValue.caseInsensitiveCompare(fieldValue) == .orderedSame { valid = false (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) - break } else { (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) } From 6d3805c9581c238739e0990794c3628eadddaa3f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 15:39:35 -0400 Subject: [PATCH 21/67] valid true --- .../FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 15bcb3f0..224d2334 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -41,7 +41,7 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { if let compareValue = compareValue, let fieldValue = formField.formFieldValue() as? String, compareValue.caseInsensitiveCompare(fieldValue) == .orderedSame { - valid = false + valid = true (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) } else { (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) From c144b07a836e591daa78eb934bb34aa588819278 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 16:14:16 -0400 Subject: [PATCH 22/67] revisions for review --- .../Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 224d2334..090812b3 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -29,23 +29,22 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { var valid = false - var compareValue: String? + var compareText: String? for formKey in fields { guard let formField = fieldMolecules[formKey] else { continue } - if compareValue == nil { - compareValue = formField.formFieldValue() as? String + guard let compareString = compareText else { + compareText = formField.formFieldValue() as? String continue } - if let compareValue = compareValue, let fieldValue = formField.formFieldValue() as? String, - compareValue.caseInsensitiveCompare(fieldValue) == .orderedSame { + if let fieldValue = formField.formFieldValue() as? String, + compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { valid = true - (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) - } else { - (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) } + + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) } return valid From 926659c12919291c1ff4883b846a54d4194f8496 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 16:15:43 -0400 Subject: [PATCH 23/67] dramatic change --- .../Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 090812b3..9f361dfd 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -34,13 +34,14 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { for formKey in fields { guard let formField = fieldMolecules[formKey] else { continue } - guard let compareString = compareText else { - compareText = formField.formFieldValue() as? String - continue + guard let compareString = compareText, + let fieldValue = formField.formFieldValue() as? String + else { + compareText = formField.formFieldValue() as? String + continue } - if let fieldValue = formField.formFieldValue() as? String, - compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { + if compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { valid = true } From ac5bf372eb1e349e133666f3bbd61e293c86c926 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 16:16:14 -0400 Subject: [PATCH 24/67] undo --- .../Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 9f361dfd..090812b3 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -34,14 +34,13 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { for formKey in fields { guard let formField = fieldMolecules[formKey] else { continue } - guard let compareString = compareText, - let fieldValue = formField.formFieldValue() as? String - else { - compareText = formField.formFieldValue() as? String - continue + guard let compareString = compareText else { + compareText = formField.formFieldValue() as? String + continue } - if compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { + if let fieldValue = formField.formFieldValue() as? String, + compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { valid = true } From 90d5093318cd0d812a269f34cc6d36213ae6fc09 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 15 May 2020 16:25:37 -0400 Subject: [PATCH 25/67] name change --- .../FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 090812b3..0bdd7ca3 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -15,7 +15,7 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { //-------------------------------------------------- public static var identifier: String = "equalsIgnoreCase" - public var type: String = RuleEqualsModel.identifier + public var type: String = RuleEqualsIgnoreCaseModel.identifier public var fields: [String] public var errorMessage: [String: String]? From f8025eb67add0e09757f0c4c1a7248fce594d946 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 18 May 2020 12:27:11 -0400 Subject: [PATCH 26/67] more room for validation --- .../Atomic/Atoms/TextFields/EntryField.swift | 27 ++++++++++++ .../Atoms/TextFields/EntryFieldModel.swift | 7 ++-- .../Atoms/TextFields/TextEntryField.swift | 41 +++++-------------- .../Atoms/TextFields/TextViewEntryField.swift | 4 ++ .../Rules/RuleEqualsIgnoreCaseModel.swift | 5 +++ 5 files changed, 50 insertions(+), 34 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 41fec6bb..65b13861 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -259,6 +259,21 @@ import UIKit resignFirstResponder() } + @objc public func updateValidation(_ isValid: Bool) { + let previousValidity = self.isValid + self.isValid = isValid + + if previousValidity && !isValid { + shouldShowError(true) + } else if (!previousValidity && isValid) { + shouldShowError(false) + } + } + + func shouldShowError(_ showError: Bool) { + self.showError = showError + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- @@ -285,6 +300,18 @@ import UIKit entryFieldContainer.set(with: model, delegateObject, additionalData) + model.updateUI = { [weak self] in + MVMCoreDispatchUtility.performBlock(onMainThread: { + guard let self = self else { return } + + if self.isSelected { + self.updateValidation(model.isValid ?? true) + } else if model.isValid ?? true && self.showError { + self.showError = false + } + }) + } + title = model.title feedback = model.feedback isEnabled = model.enabled diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 1d6e9221..dd2a3c62 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -71,12 +71,13 @@ import Foundation } public func setValidity(_ valid: Bool, rule: RulesProtocol) { - if let fieldKey = fieldKey, - let ruleErrorMessage = rule.errorMessage?[fieldKey] { + + if let fieldKey = fieldKey, let ruleErrorMessage = rule.errorMessage?[fieldKey] { self.errorMessage = ruleErrorMessage } + self.isValid = valid - + updateUI?() } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index e849fc2f..2daee169 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -236,27 +236,6 @@ import UIKit super.validateText() } - @objc public func updateValidation(_ isValid: Bool) { - let previousValidity = self.isValid - self.isValid = isValid - - if previousValidity && !isValid { - shouldShowError(true) - } else if (!previousValidity && isValid) { - shouldShowError(false) - } - } - - func shouldShowError(_ showError: Bool) { - self.showError = showError - if showError { - observingTextFieldDelegate?.isValid?(textfield: self) - entryFieldContainer.originalUI() - } else { - observingTextFieldDelegate?.isInvalid?(textfield: self) - } - } - /// Executes on UITextField.textDidBeginEditingNotification @objc override func startEditing() { super.startEditing() @@ -310,6 +289,16 @@ import UIKit } } + override func shouldShowError(_ showError: Bool) { + super.shouldShowError(showError) + + if showError { + observingTextFieldDelegate?.isValid?(textfield: self) + } else { + observingTextFieldDelegate?.isInvalid?(textfield: self) + } + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- @@ -319,16 +308,6 @@ import UIKit guard let model = model as? TextEntryFieldModel else { return } - model.updateUI = { [weak self] in - MVMCoreDispatchUtility.performBlock(onMainThread: { - guard let self = self else { return } - - if self.isSelected { - self.updateValidation(model.isValid ?? true) - } - }) - } - self.delegateObject = delegateObject FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) text = model.text diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index e08f3843..0556245d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -217,6 +217,10 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele showError = !isValid } + override func shouldShowError(_ showError: Bool) { + super.shouldShowError(showError) + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift index 0bdd7ca3..5e014cff 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -42,6 +42,11 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol { if let fieldValue = formField.formFieldValue() as? String, compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { valid = true + for formKey in fields { + guard let formField = fieldMolecules[formKey] else { continue } + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(true, rule: self) + } + break } (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) From d476b9ce14a77354bfa174a2ee4c0074346601f2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 14:55:29 -0400 Subject: [PATCH 27/67] Navigation fixing --- MVMCoreUI.xcodeproj/project.pbxproj | 28 ++++++++++-- MVMCoreUI/Atomic/Atoms/Views/Line.swift | 4 ++ .../NavigationItemButtonModel.swift | 35 +++++++++++++++ .../NavigationItemModel.swift} | 43 +------------------ .../NavigationItemModelProtocol.swift | 21 +++++++++ .../PanelNavigationItemModelProtocol.swift | 14 ++++++ .../MVMControllerModelProtocol.swift | 1 + .../Containers/NavigationController.swift | 10 ++--- .../MVMCoreUISplitViewController.h | 4 +- .../MVMCoreUISplitViewController.m | 13 ++++-- 10 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift rename MVMCoreUI/Atomic/Molecules/{NavigationItemModelProtocol.swift => NavigationBar/NavigationItemModel.swift} (70%) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ec7e68b0..59816653 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -245,7 +245,7 @@ D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */; }; D20923592450ECE00044AD09 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20923582450ECE00044AD09 /* TableView.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; - D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; }; + D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */; }; D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; }; @@ -264,6 +264,9 @@ D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; + D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; + D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */; }; + D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; }; @@ -656,7 +659,7 @@ D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerModelBase.swift; sourceTree = ""; }; D20923582450ECE00044AD09 /* TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableView.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; - D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; + D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModel.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = ""; }; D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; @@ -675,6 +678,9 @@ D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; + D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; + D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; + D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; @@ -852,6 +858,8 @@ 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */, D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, + D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, + D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -1313,6 +1321,15 @@ path = TwoColumn; sourceTree = ""; }; + D2509ED42472EE0B001BFB9D /* NavigationBar */ = { + isa = PBXGroup; + children = ( + D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */, + D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */, + ); + path = NavigationBar; + sourceTree = ""; + }; D253BB9A24587023002DE544 /* OtherContainers */ = { isa = PBXGroup; children = ( @@ -1453,6 +1470,7 @@ D29DF10E21E67A77003B2FB9 /* Molecules */ = { isa = PBXGroup; children = ( + D2509ED42472EE0B001BFB9D /* NavigationBar */, D253BB9A24587023002DE544 /* OtherContainers */, D22B38E923F4E07800490EF6 /* DesignedComponents */, D22479912316A9EF003FCCF9 /* Items */, @@ -1466,7 +1484,6 @@ 012A88EB238F084D00FE3DA1 /* FooterModel.swift */, D274CA322236A78900B01B62 /* FooterView.swift */, D260105723CF9CC500764D80 /* Doughnut */, - D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */, ); path = Molecules; sourceTree = ""; @@ -1920,6 +1937,7 @@ 8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */, 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, + D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, @@ -2119,8 +2137,10 @@ 014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */, + D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */, 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, + D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, @@ -2160,7 +2180,7 @@ D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, - D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */, + D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */, AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 62550503..d34aee06 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -55,6 +55,10 @@ import UIKit public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { self.init(frame: .zero) + addLine(to: view, edge: edge, useMargin: useMargin) + } + + open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) { view.addSubview(self) NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) } diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift new file mode 100644 index 00000000..9110bfe9 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -0,0 +1,35 @@ +// +// NavigationItemButtonModel.swift +// +// +// Created by Scott Pfeil on 5/18/20. +// + +import Foundation + +public class NavigationItemButtonModel: Codable { + var imageName: String + var action: ActionModelProtocol + + public init(with imageName: String, action: ActionModelProtocol) { + self.imageName = imageName + self.action = action + } + + private enum CodingKeys: String, CodingKey { + case imageName + case action + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + imageName = try typeContainer.decode(String.self, forKey: .imageName) + action = try typeContainer.decodeModel(codingKey: .action) + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(imageName, forKey: .imageName) + try container.encodeModel(action, forKey: .action) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift similarity index 70% rename from MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift rename to MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index f15a847a..50ae62d6 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -8,48 +8,7 @@ import Foundation -public protocol NavigationItemModelProtocol { - var title: String? { get set } - var hidden: Bool { get set } - var backgroundColor: Color? { get set } - var translucent: Bool { get set } - var tintColor: Color { get set } - var line: LineModel? { get set } - var showLeftPanelButton: Bool { get set } - var showRightPanelButton: Bool { get set } - var backButton: NavigationItemButtonModel? { get set } - var additionalLeftButtons: [NavigationItemButtonModel]? { get set } - var additionalRightButtons: [NavigationItemButtonModel]? { get set } -} - -public class NavigationItemButtonModel: Codable { - var imageName: String - var action: ActionModelProtocol - - public init(with imageName: String, action: ActionModelProtocol) { - self.imageName = imageName - self.action = action - } - - private enum CodingKeys: String, CodingKey { - case imageName - case action - } - - required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - imageName = try typeContainer.decode(String.self, forKey: .imageName) - action = try typeContainer.decodeModel(codingKey: .action) - } - - open func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(imageName, forKey: .imageName) - try container.encodeModel(action, forKey: .action) - } -} - -public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol { +public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationItemModelProtocol, MoleculeModelProtocol { public class var identifier: String { return "navigationBar" } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift new file mode 100644 index 00000000..634539d4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -0,0 +1,21 @@ +// +// NavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol NavigationItemModelProtocol { + var title: String? { get set } + var hidden: Bool { get set } + var backgroundColor: Color? { get set } + var translucent: Bool { get set } + var tintColor: Color { get set } + var line: LineModel? { get set } + var backButton: NavigationItemButtonModel? { get set } + var additionalLeftButtons: [NavigationItemButtonModel]? { get set } + var additionalRightButtons: [NavigationItemButtonModel]? { get set } +} diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift new file mode 100644 index 00000000..8f599be4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift @@ -0,0 +1,14 @@ +// +// PanelNavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PanelNavigationItemModelProtocol { + var showLeftPanelButton: Bool { get set } + var showRightPanelButton: Bool { get set } +} diff --git a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift index 579a612e..d6851d78 100644 --- a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift +++ b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift @@ -5,6 +5,7 @@ // Created by Scott Pfeil on 3/16/20. // Copyright © 2020 Verizon Wireless. All rights reserved. // +// A convenience aggregate for common MVM templates. import Foundation diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index f278236c..3497075f 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -40,6 +40,7 @@ import UIKit return navigationController } + /// Convenience function for setting navigation bar with model. public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { viewController.navigationItem.title = navigationItemModel.title viewController.navigationItem.accessibilityLabel = navigationItemModel.title @@ -54,13 +55,12 @@ import UIKit // Have the navigation title match the tint color navigationController.navigationBar.titleTextAttributes?.updateValue(tint, forKey: .foregroundColor) - // Update icons if main navigation controller. - if navigationController == MVMCoreUISession.sharedGlobal()?.navigationController, - navigationController.topViewController == viewController { - // Update line. - MVMCoreUISession.sharedGlobal()?.navigationController?.separatorView?.setStyle(navigationItemModel.line?.type ?? .standard) + // Update line. + if let navigationController = navigationController as? NavigationController { + navigationController.separatorView?.setStyle(navigationItemModel.line?.type ?? .standard) } + // Update icons if main navigation controller. if navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController { // Update Panels diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index 0c252a08..e70a8b8b 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -124,8 +124,8 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { - (nullable UIImage *)imageForBackButton; // Can overide to provide other global buttons to be on the navigation bar. -- (nullable NSArray *)additionalLeftButtons; -- (nullable NSArray *)additionalRightButtons; +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController; +- (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController; // The width of the panel when it is permanently extended. Default 320. - (CGFloat)leftPanelExtendedWidth; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index e93ad613..f5c07d04 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -106,11 +106,16 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)additionalLeftButtons { +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { + return nil; + } + UIViewController *controller = (UIViewController *)viewController; + controller.page return nil; } -- (nullable NSArray *)additionalRightButtons { +- (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { return nil; } @@ -239,7 +244,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } - NSArray *extraButtons = [self additionalLeftButtons]; + NSArray *extraButtons = [self additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController]; if (extraButtons) { [leftBarButtonItems addObjectsFromArray:extraButtons]; } @@ -410,7 +415,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.rightPanelButton) { [navigationItems addObject:self.rightPanelButton]; } - NSArray *extraButtons = [self additionalRightButtons]; + NSArray *extraButtons = [self additionalRightButtonsForViewController:(nonnull UIViewController *)viewController]; if (extraButtons) { [navigationItems addObjectsFromArray:extraButtons]; } From d4fd6d8415433176f48f5fedbc6afa051b6fce77 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 18 May 2020 15:32:56 -0400 Subject: [PATCH 28/67] removed unneeded func --- MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift index 0556245d..e08f3843 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -217,10 +217,6 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele showError = !isValid } - override func shouldShowError(_ showError: Bool) { - super.shouldShowError(showError) - } - //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- From cde8218e43db95b2b2d9b52fe54927eea91f1f80 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 21:10:50 -0400 Subject: [PATCH 29/67] navigation item button fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++-- .../NavigationBar/NavigationItemModel.swift | 6 +- .../PanelNavigationItemModelProtocol.swift | 14 ++++ MVMCoreUI/BaseClasses/BarButtonItem.swift | 71 ++++++++++++++++++- .../BaseControllers/ViewController.swift | 20 ++++-- .../Containers/NavigationController.swift | 9 ++- .../MVMCoreUISplitViewController.m | 31 +++++--- 7 files changed, 139 insertions(+), 24 deletions(-) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 7cd0c44e..0d6a0f45 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -269,9 +269,9 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; + D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; - D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */; }; D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; @@ -296,6 +296,7 @@ D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; }; D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; }; D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; }; + D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D272F5F82473163100BD1A8F /* BarButtonItem.swift */; }; D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; }; D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; }; D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; }; @@ -689,9 +690,9 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; + D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; - D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; @@ -715,6 +716,7 @@ D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = ""; }; D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = ""; }; + D272F5F82473163100BD1A8F /* BarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarButtonItem.swift; sourceTree = ""; }; D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = ""; }; D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = ""; }; @@ -871,7 +873,7 @@ D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, - D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */, + D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -1803,6 +1805,7 @@ D264FAA92440F97600D98315 /* CollectionView.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, 0A7918F423F5E7EA00772FF4 /* ImageView.swift */, + D272F5F82473163100BD1A8F /* BarButtonItem.swift */, ); path = BaseClasses; sourceTree = ""; @@ -1988,6 +1991,7 @@ D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */, 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */, AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */, + D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */, 0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */, D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */, 01004F3022721C3800991ECC /* RadioButton.swift in Sources */, @@ -2104,6 +2108,7 @@ 01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */, 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, + D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */, 94F6516D2437954100631BF9 /* Tabs.swift in Sources */, 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, @@ -2166,7 +2171,6 @@ D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */, 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, - D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 50ae62d6..38dee0d2 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -19,12 +19,14 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public var translucent: Bool public var tintColor: Color public var line: LineModel? - public var showLeftPanelButton: Bool - public var showRightPanelButton: Bool public var backButton: NavigationItemButtonModel? public var additionalLeftButtons: [NavigationItemButtonModel]? public var additionalRightButtons: [NavigationItemButtonModel]? + // Legacy, will remove once menu is gone. + public var showLeftPanelButton: Bool + public var showRightPanelButton: Bool + public init() { hidden = false translucent = false diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift new file mode 100644 index 00000000..8f599be4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift @@ -0,0 +1,14 @@ +// +// PanelNavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PanelNavigationItemModelProtocol { + var showLeftPanelButton: Bool { get set } + var showRightPanelButton: Bool { get set } +} diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index d750c79a..7ee850bc 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -6,4 +6,73 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation +public typealias BarButtonAction = (BarButtonItem) -> () + +@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + private var buttonAction: BarButtonAction? + + //-------------------------------------------------- + // MARK: - Delegate + //-------------------------------------------------- + + open weak var buttonDelegate: ButtonDelegateProtocol? + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + /// Creates the item with the passed in action. + public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.buttonAction = action + return button + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + @objc func callActionBlock(_ sender: BarButtonItem) { + buttonAction?(self) + } + + open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + buttonDelegate = delegateObject?.buttonDelegate + buttonAction = { [weak self] sender in + guard let self = self else { return } + if let data = try? actionModel.encode(using: JSONEncoder()), + let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], + delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) + } + } + } + + open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + buttonDelegate = delegateObject?.buttonDelegate + buttonAction = { [weak self] sender in + guard let self = self, + delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) + } + } +} + diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index c44a8d47..25a25e80 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -158,18 +158,26 @@ import UIKit needsUpdateUI = true view.setNeedsLayout() } - - /// Processes any new data. Called after the page is loaded the first time and on response updates for this page, - open func handleNewData() { - // TODO: remove legacy. Temporary, convert legacy to navigation model. - var navigationModel = pageModel?.navigationItem ?? NavigationItemModel() + + /// Creates a legacy navigation model. + open func createDefaultLegacyNavigationModel() -> NavigationItemModel { + let navigationModel = NavigationItemModel() navigationModel.title = pageModel?.screenHeading navigationModel.showLeftPanelButton = isMasterInitiallyAccessible() navigationModel.showRightPanelButton = isSupportInitiallyAccessible() if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true { navigationModel.line = LineModel(type: .none) } - pageModel?.navigationItem = navigationModel + return navigationModel + } + + /// Processes any new data. Called after the page is loaded the first time and on response updates for this page, + open func handleNewData() { + // TODO: remove legacy. Temporary, convert legacy to navigation model. + if pageModel?.navigationItem == nil { + pageModel?.navigationItem = createDefaultLegacyNavigationModel() + } + if formValidator == nil { let rules = pageModel?.formRules formValidator = FormValidator(rules) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 4150da12..5402cae1 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -63,10 +63,13 @@ import UIKit // Update icons if main navigation controller. if navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController { - // Update Panels - MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(navigationItemModel.showLeftPanelButton , for: viewController) - MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(navigationItemModel.showRightPanelButton , for: viewController) MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + + // Update Panels + if let model = navigationItemModel as? PanelNavigationItemModelProtocol { + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) + MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) + } } } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index f5c07d04..dfc2fda3 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -12,6 +12,7 @@ @import MVMCore.MVMCoreViewManagerProtocol; @import MVMCore.MVMCoreObject; @import MVMCore.MVMCoreActionUtility; +@import MVMCore.NSDictionary_MFConvenience; #import "MVMCoreUIUtility.h" #import "UIColor+MFConvenience.h" #import "NSLayoutConstraint+MFConvenience.h" @@ -106,17 +107,31 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { - return nil; +- (nullable NSArray *)createNavigationItemsFrom:(nonnull NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + if (JSONlist.count == 0) { return nil; } + NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; + for (NSDictionary *itemData in JSONlist) { + UIImage *image = [UIImage imageNamed:[itemData string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; + BarButtonItem *item = [BarButtonItem createWith:image actionMap:[itemData dict:@"action"] delegateObject:delegateObject additionalData:nil]; + [items addObject:item]; } + return items; +} + +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } UIViewController *controller = (UIViewController *)viewController; - controller.page - return nil; + NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { - return nil; + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } + UIViewController *controller = (UIViewController *)viewController; + NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (CGFloat)leftPanelExtendedWidth { @@ -244,7 +259,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } - NSArray *extraButtons = [self additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController]; + NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController]; if (extraButtons) { [leftBarButtonItems addObjectsFromArray:extraButtons]; } @@ -415,7 +430,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.rightPanelButton) { [navigationItems addObject:self.rightPanelButton]; } - NSArray *extraButtons = [self additionalRightButtonsForViewController:(nonnull UIViewController *)viewController]; + NSArray *extraButtons = [self additionalRightButtonsForViewController:viewController]; if (extraButtons) { [navigationItems addObjectsFromArray:extraButtons]; } From fc8f189b77a7ae394c050f3af59f05fa195fe9ab Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 21:54:21 -0400 Subject: [PATCH 30/67] fix funny defect --- MVMCoreUI/BaseControllers/ViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 25a25e80..782deae2 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -175,7 +175,8 @@ import UIKit open func handleNewData() { // TODO: remove legacy. Temporary, convert legacy to navigation model. if pageModel?.navigationItem == nil { - pageModel?.navigationItem = createDefaultLegacyNavigationModel() + let navigationItem = createDefaultLegacyNavigationModel() + pageModel?.navigationItem = navigationItem } if formValidator == nil { From 76326a1a34ddb06df3c088bad9805aced781a623 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 19 May 2020 09:42:35 -0400 Subject: [PATCH 31/67] modal accessibility --- .../Items/MoleculeCollectionViewCell.swift | 8 ++-- .../Templates/ModalMoleculeListTemplate.swift | 12 +++++- .../Templates/MoleculeListTemplate.swift | 1 + .../BaseClasses/CollectionViewCell.swift | 37 ++++++++++++++----- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift index 10b51bff..2306dc94 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift @@ -10,10 +10,11 @@ import UIKit /// A collection item that is a container for any molecule. open class MoleculeCollectionViewCell: CollectionViewCell { - + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let collectionModel = model as? MoleculeCollectionItemModel else { return } + if molecule == nil { if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(collectionModel.molecule, delegateObject: delegateObject, additionalData: additionalData) { addMolecule(moleculeView) @@ -21,16 +22,15 @@ open class MoleculeCollectionViewCell: CollectionViewCell { } else { molecule?.set(with: collectionModel.molecule, delegateObject, additionalData) } - + guard let molecule = molecule as? (UIView & MVMCoreUIViewConstrainingProtocol) else { return } containerHelper.set(with: collectionModel, for: molecule) - accessibilityElements = molecule.subviews } open override func reset() { super.reset() molecule?.reset() - backgroundColor = .white + backgroundColor = .mvmWhite } open class func nameForReuse(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift index a141ef0e..63140e6e 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift @@ -8,6 +8,7 @@ import UIKit + open class ModalMoleculeListTemplate: MoleculeListTemplate { //-------------------------------------------------- // MARK: - Properties @@ -15,13 +16,20 @@ open class ModalMoleculeListTemplate: MoleculeListTemplate { public var closeButton: Button? + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + override open func handleNewData() { super.handleNewData() + closeButton = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { _ in MVMCoreNavigationHandler.shared()?.removeCurrentViewController() }) - + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() accessibilityElements = [closeButton as Any, tableView as Any] - UIAccessibility.post(notification: .layoutChanged, argument: closeButton) } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 521a0d45..4be4e025 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -8,6 +8,7 @@ import UIKit + open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol { //-------------------------------------------------- // MARK: - Stored Properties diff --git a/MVMCoreUI/BaseClasses/CollectionViewCell.swift b/MVMCoreUI/BaseClasses/CollectionViewCell.swift index e11b350c..aa74d229 100644 --- a/MVMCoreUI/BaseClasses/CollectionViewCell.swift +++ b/MVMCoreUI/BaseClasses/CollectionViewCell.swift @@ -8,9 +8,13 @@ import Foundation + /// A base collection view cell with basic mvm functionality. open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCoreViewProtocol, CollectionTemplateItemProtocol { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // Convenience helpers open var molecule: MoleculeViewProtocol? public let containerHelper = ContainerHelper() @@ -18,9 +22,13 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo /// The width, used for establishing columns open var width: CGFloat? - + private var initialSetupPerformed = false - + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - Inits public override init(frame: CGRect) { super.init(frame: .zero) @@ -39,6 +47,10 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo } } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol open func setupView() { isAccessibilityElement = false @@ -58,15 +70,19 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo open func reset() { molecule?.reset() - backgroundColor = .white + backgroundColor = .mvmWhite width = nil } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? CollectionItemModelProtocol else { return } self.model = model - + if let moleculeModel = model as? MoleculeModelProtocol, let backgroundColor = moleculeModel.backgroundColor { self.backgroundColor = backgroundColor.uiColor @@ -84,8 +100,11 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo containerHelper.constrainView(molecule) self.molecule = molecule } - + + //-------------------------------------------------- // MARK: - CollectionTemplateItemProtocol + //-------------------------------------------------- + public func set(width: CGFloat) { self.width = width } @@ -94,11 +113,11 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo override open func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes) guard let width = width else { return autoLayoutAttributes } - + let targetSize = CGSize(width: width, height: 0) - let newSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.defaultLow) + let newSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow) let newFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: newSize) autoLayoutAttributes.frame = newFrame return autoLayoutAttributes - } + } } From cbe1c043867987ba1e7d2ea90c04e26a9646c893 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 10:42:08 -0400 Subject: [PATCH 32/67] fix to action block MF call super --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 7ee850bc..9c09016b 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -27,21 +27,21 @@ public typealias BarButtonAction = (BarButtonItem) -> () /// Creates the item with the passed in action. public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.buttonAction = action return button } From bb506717114c48c242f352ba4d9ba18e587a2f87 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 12:48:56 -0400 Subject: [PATCH 33/67] target issue fix --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 38 +++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 9c09016b..51142a5a 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -8,41 +8,51 @@ public typealias BarButtonAction = (BarButtonItem) -> () -@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- +@objc fileprivate class ActionDelegate: NSObject { + fileprivate var buttonAction: BarButtonAction? + @objc fileprivate func callActionBlock(_ sender: BarButtonItem) { + buttonAction?(sender) + } +} - private var buttonAction: BarButtonAction? +@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - + private var actionObject: ActionDelegate? + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- + public static func create(with image: UIImage) -> Self { + let actionObject = ActionDelegate() + let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionObject = actionObject + return button + } + /// Creates the item with the passed in action. public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) + let button = create(with: image) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) + let button = create(with: image) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) - button.buttonAction = action + let button = create(with: image) + button.actionObject?.buttonAction = action return button } @@ -50,13 +60,9 @@ public typealias BarButtonAction = (BarButtonItem) -> () // MARK: - Methods //-------------------------------------------------- - @objc func callActionBlock(_ sender: BarButtonItem) { - buttonAction?(self) - } - open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - buttonAction = { [weak self] sender in + actionObject?.buttonAction = { [weak self] sender in guard let self = self else { return } if let data = try? actionModel.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], @@ -68,7 +74,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - buttonAction = { [weak self] sender in + actionObject?.buttonAction = { [weak self] sender in guard let self = self, delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) From d203285c738a3f82fdf22429926f38128382650e Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 19:05:55 -0400 Subject: [PATCH 34/67] Cleanup navigation button creation. --- .../NavigationItemButtonModel.swift | 6 +++ MVMCoreUI/BaseClasses/BarButtonItem.swift | 8 +-- .../Containers/NavigationController.swift | 54 ++++++++++++++----- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift index 9110bfe9..7a81cb5b 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -32,4 +32,10 @@ public class NavigationItemButtonModel: Codable { try container.encode(imageName, forKey: .imageName) try container.encodeModel(action, forKey: .action) } + + /// Convenience function that creates a BarButtonItem for the model. + public func createNavigationItem(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) + return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + } } diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 51142a5a..a2a2e9e6 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -28,7 +28,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () // MARK: - Initializers //-------------------------------------------------- - public static func create(with image: UIImage) -> Self { + public static func create(with image: UIImage?) -> Self { let actionObject = ActionDelegate() let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) button.actionObject = actionObject @@ -36,21 +36,21 @@ public typealias BarButtonAction = (BarButtonItem) -> () } /// Creates the item with the passed in action. - public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { let button = create(with: image) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. - public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { let button = create(with: image) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. - public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { + public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { let button = create(with: image) button.actionObject?.buttonAction = action return button diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 5402cae1..67506221 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -11,35 +11,60 @@ import UIKit @objcMembers open class NavigationController: UINavigationController { public var separatorView: Line? + /// Getter for the main navigation controller public static func navigationController() -> Self? { return MVMCoreActionUtility.initializerClassCheck(MVMCoreUISession.sharedGlobal()?.navigationController, classToVerify: self) as? Self } - public static func style(_ navigationBar: UINavigationBar) { + /// Provides MVM styling to the navigation bar. Returns a reference to the line. + public static func style(_ navigationBar: UINavigationBar) -> Line { UIColor.mfSetBackgroundColor(forNavigationBar: .white, navigationBar: navigationBar, transparent: false) navigationBar.shadowImage = UIImage() navigationBar.isOpaque = true navigationBar.tintColor = .black navigationBar.titleTextAttributes = [NSAttributedString.Key.font: MFStyler.fontBoldBodySmall(false)]; + return Line(pinTo: navigationBar, edge: .bottom, useMargin: false) } + /// Sets up the application with a navigation controller public static func setupNavigationController() -> Self? { let navigationController = self.init() - style(navigationController.navigationBar) - navigationController.separatorView = Line(pinTo: navigationController.navigationBar, edge: .bottom, useMargin: false) - navigationController.separatorView?.setStyle(.standard) + navigationController.separatorView = style(navigationController.navigationBar) MVMCoreUISession.sharedGlobal()?.navigationController = navigationController MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController MVMCoreNavigationHandler.shared()?.navigationController = navigationController return navigationController } + /// Sets up the application with a navigation controller as the main container. public static func setupNavigationControllerAsMainController() -> Self? { guard let navigationController = setupNavigationController() else { return nil } MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController) return navigationController } + /// Convenience function for setting the navigation buttons. + public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + var items: [UIBarButtonItem] = [] + if let backButtonModel = navigationItemModel.backButton, + navigationController.viewControllers.count > 1 { + items.append(backButtonModel.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + if let itemModels = navigationItemModel.additionalLeftButtons { + for item in itemModels { + items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + viewController.navigationItem.leftBarButtonItems = items + } + if let itemModels = navigationItemModel.additionalRightButtons { + for item in itemModels { + items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + viewController.navigationItem.rightBarButtonItems = items + } + } + /// Convenience function for setting navigation bar with model. public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { viewController.navigationItem.title = navigationItemModel.title @@ -60,16 +85,21 @@ import UIKit navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none } + // Let legacy splitview controller handle buttons for now. + guard navigationController == MVMCoreUISplitViewController.main()?.splitViewController?.navigationController, + navigationController.topViewController == viewController else { + // Not the main split view controller, add buttons. + setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + return + } + // Update icons if main navigation controller. - if navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController { - MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) - // Update Panels - if let model = navigationItemModel as? PanelNavigationItemModelProtocol { - MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) - MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) - } + // Update Panels + if let model = navigationItemModel as? PanelNavigationItemModelProtocol { + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) + MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) } } } From 5a55312c9dea70fd3ceccac0924c3a59e9c70245 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 19:57:02 -0400 Subject: [PATCH 35/67] typo fix --- MVMCoreUI/Containers/NavigationController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 67506221..170ce5b3 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -86,7 +86,7 @@ import UIKit } // Let legacy splitview controller handle buttons for now. - guard navigationController == MVMCoreUISplitViewController.main()?.splitViewController?.navigationController, + guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController else { // Not the main split view controller, add buttons. setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) From 4453b24d4d7fdefd0e669644fe4500683df02608 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Wed, 20 May 2020 16:00:44 +0530 Subject: [PATCH 36/67] 21041(iOS - List - Left Variable - Icon - All Text & Links) initial commit. Created Model and Molecule class. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../ListLeftVariableIconAllTextLinks.swift | 54 +++++++++++++++++++ ...istLeftVariableIconAllTextLinksModel.swift | 49 +++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 08865ee9..ba954d23 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -198,6 +198,8 @@ AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */; }; AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */; }; AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; }; + AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */; }; + AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; AAB7EDEF246ADA1600E54929 /* ListProgressBarThinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */; }; @@ -615,6 +617,8 @@ AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyText.swift; sourceTree = ""; }; AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyTextModel.swift; sourceTree = ""; }; AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = ""; }; + AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinksModel.swift; sourceTree = ""; }; + AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinks.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListProgressBarThinModel.swift; sourceTree = ""; }; @@ -1283,6 +1287,8 @@ 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */, 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */, + AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */, + AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */, ); path = LeftVariable; sourceTree = ""; @@ -2151,6 +2157,7 @@ D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, 011D958524042432000E3791 /* RulesProtocol.swift in Sources */, + AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */, AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, @@ -2244,6 +2251,7 @@ 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, 525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */, + AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index dbff52fe..e46cfed0 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -146,6 +146,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift new file mode 100644 index 00000000..f53134a1 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinks.swift @@ -0,0 +1,54 @@ +// +// ListLeftVariableIconAllTextLinks.swift +// MVMCoreUI +// +// Created by Lekshmi S on 20/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers open class ListLeftVariableIconAllTextLinks: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + public let leftImage = LoadImageView() + public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public var stack: Stack + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //-------------------------------------------------- + // MARK: - Life Cycle + //-------------------------------------------------- + override open func setupView() { + super.setupView() + leftImage.addSizeConstraintsForAspectRatio = true + leftImage.imageView.contentMode = .scaleAspectFit + addMolecule(stack) + stack.restack() + } + + //------------------------------------------------------ + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableIconAllTextLinksModel else { return } + leftImage.set(with: model.image, delegateObject, additionalData) + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 140 + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift new file mode 100644 index 00000000..8e35984a --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift @@ -0,0 +1,49 @@ +// +// ListLeftVariableIconAllTextLinksModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 20/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +public class ListLeftVariableIconAllTextLinksModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listLVImgAll" + public var image: ImageViewModel + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + + override public func setDefaults() { + super.setDefaults() + if image.width == nil, image.height == nil { + image.width = 30 + image.height = 30 + } + } + + public init(image: ImageViewModel, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) { + self.image = image + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case image + case eyebrowHeadlineBodyLink + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(image, forKey: .image) + try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + } +} From 5bda356dc9cb8dcf48d3171c31ee141c186eeafd Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 11:00:02 -0400 Subject: [PATCH 37/67] Back button fix --- .../NavigationItemButtonModel.swift | 2 +- .../Containers/NavigationController.swift | 6 +-- .../MVMCoreUISplitViewController.m | 46 ++++++++++++++----- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift index 7a81cb5b..26be6952 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -34,7 +34,7 @@ public class NavigationItemButtonModel: Codable { } /// Convenience function that creates a BarButtonItem for the model. - public func createNavigationItem(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 170ce5b3..d62dec40 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -49,17 +49,17 @@ import UIKit var items: [UIBarButtonItem] = [] if let backButtonModel = navigationItemModel.backButton, navigationController.viewControllers.count > 1 { - items.append(backButtonModel.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let itemModels = navigationItemModel.additionalLeftButtons { for item in itemModels { - items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.leftBarButtonItems = items } if let itemModels = navigationItemModel.additionalRightButtons { for item in itemModels { - items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.rightBarButtonItems = items } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index dfc2fda3..d9814a1f 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -107,15 +107,13 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)createNavigationItemsFrom:(nonnull NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - if (JSONlist.count == 0) { return nil; } - NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; - for (NSDictionary *itemData in JSONlist) { - UIImage *image = [UIImage imageNamed:[itemData string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; - BarButtonItem *item = [BarButtonItem createWith:image actionMap:[itemData dict:@"action"] delegateObject:delegateObject additionalData:nil]; - [items addObject:item]; - } - return items; +- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; } + UIViewController *controller = (UIViewController *)viewController; + NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]]; + if (!item) { return self.backButton; } + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { @@ -123,7 +121,7 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = (UIViewController *)viewController; NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { @@ -131,7 +129,7 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = (UIViewController *)viewController; NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (CGFloat)leftPanelExtendedWidth { @@ -254,7 +252,13 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; if ([viewController.navigationController.viewControllers count] > 1) { - [leftBarButtonItems addObject:self.backButton]; + UIBarButtonItem *button = [self getBackButtonForViewController:viewController]; + if (button) { + viewController.navigationItem.hidesBackButton = YES; + [leftBarButtonItems addObject:button]; + } else { + viewController.navigationItem.hidesBackButton = NO; + } } if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; @@ -621,6 +625,24 @@ CGFloat const PanelAnimationDuration = 0.2; #pragma mark - Other Panel Functions +/// Convenience function, creates a BarButtonItem from button json +- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; + BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil]; + return item; +} + +/// Convenience function, creates a list of BarButtonItems list of json +- (nullable NSArray *)createNavigationItemButtonsFrom:(nullable NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + if (JSONlist.count == 0) { return nil; } + NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; + for (NSDictionary *itemData in JSONlist) { + UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject]; + [items addObject:item]; + } + return items; +} + - (void)forceHideBothDrawers { [self hideBothDrawersShouldForceHide:YES]; } From 5e7745655755b7756e3c0a10326b9a630089f6cb Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 20 May 2020 16:05:09 -0400 Subject: [PATCH 38/67] removing unneeded caret statement --- MVMCoreUI/BaseClasses/TableViewCell.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index f07b1ee2..254a09f0 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -206,7 +206,6 @@ import UIKit caret.translatesAutoresizingMaskIntoConstraints = true caret.isAccessibilityElement = true caret.accessibilityTraits = .button - caret.accessibilityLabel = "Caret," caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint") caret.size = .small(.vertical) if let size = caret.size?.dimensions() { From 93e84cf3e417d6ada6a686f0aa348d7d2fdeae65 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 17:25:49 -0400 Subject: [PATCH 39/67] first change --- MVMCoreUI/Atomic/Organisms/Carousel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 4cf65f1b..30d4c21e 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -173,7 +173,7 @@ open class Carousel: View { numberOfPages = newMolecules.count molecules = newMolecules - if carouselModel?.loop ?? false && newMolecules.count > 2 { + if carouselModel?.loop ?? false && newMolecules.count > 1 { // Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell). loop = true From d40f41e7bb9671fcdbeb5596634a2f105539e286 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 19:38:37 -0400 Subject: [PATCH 40/67] cleaning --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++++ .../Atomic/Molecules/Items/CarouselItem.swift | 2 +- MVMCoreUI/Atomic/Organisms/Carousel.swift | 18 ++++++++---------- MVMCoreUI/Atomic/Organisms/CarouselModel.swift | 8 ++++---- .../CarouselItemModelProtocol.swift | 4 +--- .../ModelProtocols/CarouselItemProtocol.swift | 15 +++++++++++++++ 6 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d7afb970..7b35fc55 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -266,6 +266,7 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; @@ -680,6 +681,7 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; @@ -850,6 +852,7 @@ children = ( D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */, 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */, + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */, 012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */, 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */, 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */, @@ -2226,6 +2229,7 @@ 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, 525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift index 3089596a..a37fe016 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift @@ -8,7 +8,7 @@ import Foundation -open class CarouselItem: MoleculeCollectionViewCell { +open class CarouselItem: MoleculeCollectionViewCell, CarouselItemProtocol { open var allowsPeaking = false var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate)) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 30d4c21e..9fa72b5d 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -36,7 +36,7 @@ open class Carousel: View { open var numberOfPages = 0 /// The models for the molecules. - var molecules: [MoleculeModelProtocol]? + var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]? /// The horizontal alignment of the cell in the collection view. Only noticeable if the itemWidthPercent is less than 100%. public var itemAlignment = UICollectionView.ScrollPosition.left @@ -176,11 +176,9 @@ open class Carousel: View { if carouselModel?.loop ?? false && newMolecules.count > 1 { // Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell). loop = true - - molecules?.insert(newMolecules.last!, at: 0) - molecules?.insert(newMolecules[(newMolecules.count - 2)], at: 0) - molecules?.append(newMolecules.first!) - molecules?.append(newMolecules[1]) + + molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0) + molecules?.append(contentsOf: newMolecules.prefix(2)) } pageIndex = 0 @@ -259,15 +257,15 @@ open class Carousel: View { let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row } if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex { - (collectionView.cellForItem(at: firstItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: firstItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } if let lastItem = visibleItemsPaths.last, lastItem.row != currentIndex { - (collectionView.cellForItem(at: lastItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: lastItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } } else { // Hide peaking. for item in collectionView.visibleCells { - (item as? CarouselItem)?.setPeaking(false, animated: true) + (item as? CarouselItemProtocol)?.setPeaking(false, animated: true) } } } @@ -301,7 +299,7 @@ extension Carousel: UICollectionViewDelegateFlowLayout { } open func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { - (cell as? CarouselItem)?.setPeaking(false, animated: false) + (cell as? CarouselItemProtocol)?.setPeaking(false, animated: false) } } diff --git a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift index 857901e8..5ff753aa 100644 --- a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift @@ -19,7 +19,7 @@ import UIKit } public var backgroundColor: Color? - public var molecules: [CarouselItemModel] + public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] public var index: Int = 0 public var spacing: Float? public var border: Bool? @@ -29,7 +29,7 @@ import UIKit public var itemAlignment: UICollectionView.ScrollPosition? public var pagingMolecule: (CarouselPagingModelProtocol & MoleculeModelProtocol)? - public init(molecules: [CarouselItemModel]) { + public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) { self.molecules = molecules } @@ -57,7 +57,7 @@ import UIKit required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decode([CarouselItemModel].self, forKey: .molecules) + molecules = try typeContainer.decodeModels(codingKey: .molecules) index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) spacing = try typeContainer.decodeIfPresent(Float.self, forKey: .spacing) @@ -73,7 +73,7 @@ import UIKit var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encode(molecules, forKey: .molecules) + try container.encodeModels(molecules, forKey: .molecules) try container.encode(spacing, forKey: .spacing) try container.encode(border, forKey: .border) try container.encode(loop, forKey: .loop) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift index 093c9337..198cf80d 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift @@ -9,7 +9,5 @@ import Foundation -public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { - var peakingUI: Bool? { get } - var peakingArrowColor: Color? { get } +public protocol CarouselItemModelProtocol: ContainerModelProtocol { } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift new file mode 100644 index 00000000..4f49e5f7 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift @@ -0,0 +1,15 @@ +// +// CarouselItemProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol CarouselItemProtocol: UICollectionViewCell { + + /// Notifies the cell if it is peaking or not. + func setPeaking(_ peaking: Bool, animated: Bool) +} From 79127889dd7e8fecaefbee688069cc54e8166d2d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 20:28:13 -0400 Subject: [PATCH 41/67] name change --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index a2a2e9e6..ac26c040 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -22,7 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - private var actionObject: ActionDelegate? + private var actionDelegate: ActionDelegate? //-------------------------------------------------- // MARK: - Initializers @@ -31,7 +31,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () public static func create(with image: UIImage?) -> Self { let actionObject = ActionDelegate() let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) - button.actionObject = actionObject + button.actionDelegate = actionObject return button } @@ -52,7 +52,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () /// Creates the item with the passed in action. public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { let button = create(with: image) - button.actionObject?.buttonAction = action + button.actionDelegate?.buttonAction = action return button } @@ -62,11 +62,10 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - actionObject?.buttonAction = { [weak self] sender in - guard let self = self else { return } + actionDelegate?.buttonAction = { sender in if let data = try? actionModel.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], - delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } @@ -74,9 +73,8 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - actionObject?.buttonAction = { [weak self] sender in - guard let self = self, - delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } + actionDelegate?.buttonAction = { sender in + guard delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } From 518672f4f37433061ea3ccbde7fbcb414842b6ec Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 20:40:22 -0400 Subject: [PATCH 42/67] addressing review comments --- MVMCoreUI/Containers/NavigationController.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index d62dec40..3f7846a0 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -51,14 +51,14 @@ import UIKit navigationController.viewControllers.count > 1 { items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } - if let itemModels = navigationItemModel.additionalLeftButtons { - for item in itemModels { + if let leftItemModels = navigationItemModel.additionalLeftButtons { + for item in leftItemModels { items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.leftBarButtonItems = items } - if let itemModels = navigationItemModel.additionalRightButtons { - for item in itemModels { + if let rightItemModels = navigationItemModel.additionalRightButtons { + for item in rightItemModels { items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.rightBarButtonItems = items From b5bd23c38c2f32af5b97e977987f9eb502b0f70a Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Thu, 21 May 2020 15:41:24 +0530 Subject: [PATCH 43/67] 21042(iOS - List - Left Variable - Icon - With Right Caret - Body Text) initial commit. Added model and molecule class files. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + ...ftVariableIconWithRightCaretBodyText.swift | 78 +++++++++++++++++++ ...iableIconWithRightCaretBodyTextModel.swift | 56 +++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ba954d23..1238577b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -181,6 +181,8 @@ 94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */; }; 94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */; }; 94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; }; + AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */; }; + AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */; }; AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */; }; AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */; }; AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */; }; @@ -600,6 +602,8 @@ 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Bold.otf"; sourceTree = ""; }; 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = ""; }; 94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = ""; }; + AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyTextModel.swift; sourceTree = ""; }; + AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyText.swift; sourceTree = ""; }; AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Buttons.swift; sourceTree = ""; }; AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2ButtonsModel.swift; sourceTree = ""; }; AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePayments.swift; sourceTree = ""; }; @@ -1289,6 +1293,8 @@ 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */, AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */, AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */, + AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */, + AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */, ); path = LeftVariable; sourceTree = ""; @@ -1943,6 +1949,7 @@ files = ( AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */, 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */, + AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */, 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */, 943784F5236B77BB006A1E82 /* Wheel.swift in Sources */, @@ -2309,6 +2316,7 @@ 8D3BA9BD2433787000D341BA /* ListThreeColumnInternationalDataDividerModel.swift in Sources */, D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */, 011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */, + AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */, 011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */, 01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */, 0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index e46cfed0..d29b652a 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -147,6 +147,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift new file mode 100644 index 00000000..626d9c19 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift @@ -0,0 +1,78 @@ +// +// ListLeftVariableIconWithRightCaretBodyText.swift +// MVMCoreUI +// +// Created by Lekshmi S on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers open class ListLeftVariableIconWithRightCaretBodyText: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //------------------------------------------------------- + public let leftImage = LoadImageView() + public let headlineBody = HeadlineBody() + public let rightLabel = Label.commonLabelB2(true) + private let rightLabelStackItem: StackItem + public var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + rightLabelStackItem = StackItem(andContain: rightLabel) + let stackItems = [StackItem(andContain: leftImage), StackItem(andContain: headlineBody), rightLabelStackItem] + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill), StackItemModel(spacing: 4, horizontalAlignment: .trailing)], axis: .horizontal) + stack = Stack(with: stackModel, stackItems: stackItems) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open override func alignAccessoryToHero() -> CGPoint? { + // Ensures that the right label is centered vertically with headline. + let heroCenter = super.alignAccessoryToHero() + if let heroCenter = heroCenter { + let convertedPoint = stack.convert(heroCenter, from: self) + rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY + } + return heroCenter + } + + //----------------------------------------------------- + // MARK: - View Lifecycle + //------------------------------------------------------- + override open func setupView() { + super.setupView() + leftImage.addSizeConstraintsForAspectRatio = true + leftImage.contentMode = .scaleAspectFit + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.numberOfLines = 1 + addMolecule(stack) + stack.restack() + } + + //---------------------------------------------------- + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableIconWithRightCaretBodyTextModel else { return} + leftImage.set(with: model.image, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 90 + } + + open override func reset() { + super.reset() + rightLabel.styleB2(true) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift new file mode 100644 index 00000000..e2bd5d90 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift @@ -0,0 +1,56 @@ +// +// ListLeftVariableIconWithRightCaretBodyTextModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +public class ListLeftVariableIconWithRightCaretBodyTextModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listLVImgBdy" + public var image: ImageViewModel + public var headlineBody: HeadlineBodyModel + public var rightLabel: LabelModel + + override public func setDefaults() { + super.setDefaults() + if image.width == nil, image.height == nil { + image.width = 30 + image.height = 30 + } + headlineBody.style = .item + headlineBody.headline?.hero = 0 + } + + public init(image: ImageViewModel, headlineBody: HeadlineBodyModel, rightLabel: LabelModel) { + self.image = image + self.headlineBody = headlineBody + self.rightLabel = rightLabel + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case image + case headlineBody + case rightLabel + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(image, forKey: .image) + try container.encode(headlineBody, forKey: .headlineBody) + try container.encode(rightLabel, forKey: .rightLabel) + } +} From 7bf03d941845d26e6c89ad6a792bd145bf344f67 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Thu, 21 May 2020 14:38:56 -0400 Subject: [PATCH 44/67] add button border and text color change to actionhandler setter. --- MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index eeff9cfe..a882035e 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -248,6 +248,8 @@ // Sets the color if (color) { + self.button.layer.borderColor = color.CGColor; + [self.button setTitleColor:color forState:UIControlStateNormal]; [self.closeButton setTintColor:color]; } From 5f1fa847db4f70f91915863cdf1cbe164de24dfc Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Thu, 21 May 2020 15:09:04 -0400 Subject: [PATCH 45/67] squash feature/list_leftvariable_numberedlist_alltextlinks --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + ...tVariableNumberedListAllTextAndLinks.swift | 60 +++++++++++++++++++ ...ableNumberedListAllTextAndLinksModel.swift | 42 +++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b8fbede1..292e4157 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -114,6 +114,8 @@ 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; + 32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */; }; + 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */; }; 522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; }; 522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */; }; 52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */; }; @@ -537,6 +539,8 @@ 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; + 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinksModel.swift; sourceTree = ""; }; + 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinks.swift; sourceTree = ""; }; 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = ""; }; 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinksModel.swift; sourceTree = ""; }; 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinks.swift; sourceTree = ""; }; @@ -1299,6 +1303,8 @@ 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */, AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */, AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */, + 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */, + 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */, ); path = LeftVariable; sourceTree = ""; @@ -1971,6 +1977,7 @@ 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, + 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, @@ -2180,6 +2187,7 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, + 32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */, 011D958524042432000E3791 /* RulesProtocol.swift in Sources */, AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */, AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index e46cfed0..18b3fee7 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -147,6 +147,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift new file mode 100644 index 00000000..e7a35cc6 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -0,0 +1,60 @@ +// +// ListLeftVariableNumberedListAllTextAndLinks.swift +// MVMCoreUI +// +// Created by Subhankar Acharya on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListLeftVariableNumberedListAllTextAndLinks: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + public let leftLabel = Label.createLabelTitle2XLarge(true) + public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public var stack: Stack + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)), + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //-------------------------------------------------- + // MARK: - Life Cycle + //-------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + //------------------------------------------------------ + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableNumberedListAllTextAndLinksModel else { return } + leftLabel.text = String(model.number) + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 140 + } + + open override func reset() { + super.reset() + leftLabel.styleTitle2XLarge(true) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift new file mode 100644 index 00000000..78a85a8e --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift @@ -0,0 +1,42 @@ +// +// ListLeftVariableNumberedListAllTextAndLinksModel.swift +// MVMCoreUI +// +// Created by Subhankar Acharya on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListLeftVariableNumberedListAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listLVNAll" + public var number: Int + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + + public init(number: Int, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) { + self.number = number + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case number + case eyebrowHeadlineBodyLink + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + number = try typeContainer.decode(Int.self, forKey: .number) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(number, forKey: .number) + try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + } +} From 648da2bd3f7e43e6e1fa0a63378455a5d277366a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 21 May 2020 15:29:24 -0400 Subject: [PATCH 46/67] Bug fix in label --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 087e893c..598f3f4e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -677,6 +677,9 @@ public typealias ActionBlock = () -> () @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber + // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. + preferredMaxLayoutWidth = size + if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) From 3f0828fa44e064785dd4ad6b89b165529c5bec7c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 21 May 2020 16:46:01 -0400 Subject: [PATCH 47/67] disabled and init --- .../Atomic/Atoms/Buttons/CaretLink.swift | 7 ++----- .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 19 +++++++++++++------ MVMCoreUI/Atomic/Atoms/Views/Line.swift | 8 +------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift index 0e2dfd7b..b0822480 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift @@ -143,11 +143,8 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { backgroundColor = color.uiColor } - enabledColor = (model.inverted ? model.enabled_inverted : model.enabledColor).uiColor - - if let color = model.disabledColor { - disabledColor = color.uiColor - } + enabledColor = (model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor + disabledColor = (model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor isEnabled = model.enabled set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 5b48deea..5a4a4c14 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -20,8 +20,9 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabledColor: Color = Color(uiColor: .mvmBlack) - public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6) - public var enabled_inverted: Color = Color(uiColor: .mvmWhite) + public var disabledColor: Color = Color(uiColor: .mvmCoolGray6) + public var enabledColor_inverted: Color = Color(uiColor: .mvmWhite) + public var disabledColor_inverted: Color = Color(uiColor: .mvmCoolGray10) public var enabled = true public var inverted = false @@ -42,7 +43,8 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { case backgroundColor case title case action - case enabled_inverted + case enabledColor_inverted + case disabledColor_inverted case enabledColor case disabledColor case enabled @@ -60,8 +62,12 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) - if let enabled_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabled_inverted) { - self.enabled_inverted = enabled_inverted + if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) { + self.enabledColor_inverted = enabledColor_inverted + } + + if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) { + self.disabledColor_inverted = disabledColor_inverted } if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { @@ -92,7 +98,8 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(enabled, forKey: .enabledColor) try container.encodeIfPresent(disabledColor, forKey: .disabledColor) try container.encode(enabled, forKey: .enabled) - try container.encode(enabled_inverted, forKey: .enabled_inverted) + try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted) + try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted) try container.encode(inverted, forKey: .inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 7e05e2fa..22d33b1f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -47,9 +47,7 @@ import UIKit public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { self.init(frame: .zero) - - view.addSubview(self) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) + addLine(to: view, edge: edge, useMargin: useMargin) } //-------------------------------------------------- @@ -84,10 +82,6 @@ import UIKit //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- - public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { - self.init(frame: .zero) - addLine(to: view, edge: edge, useMargin: useMargin) - } open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) { view.addSubview(self) From 740545e9c30fcbc8eada62fba137727eb1d0e126 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 15:30:02 -0400 Subject: [PATCH 48/67] Try again --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 15 +++++++-------- ...tLeftVariableNumberedListAllTextAndLinks.swift | 3 ++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 598f3f4e..35d45ac6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -674,12 +674,15 @@ public typealias ActionBlock = () -> () setScale(scale) } + open override func layoutSubviews() { + super.layoutSubviews() + + // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. + preferredMaxLayoutWidth = frame.width + } + @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber - - // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. - preferredMaxLayoutWidth = size - if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) @@ -878,10 +881,6 @@ extension Label { return true } - public func horizontalAlignment() -> UIStackView.Alignment { - return .leading - } - public func copyBackgroundColor() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index e7a35cc6..9f2d62c9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -21,7 +21,7 @@ import Foundation //-------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)), - (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .fill))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -35,6 +35,7 @@ import Foundation //-------------------------------------------------- override open func setupView() { super.setupView() + leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) addMolecule(stack) stack.restack() } From 528ae8a6854e1f137d804f6017a1e4f39bc32ecb Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 16:25:12 -0400 Subject: [PATCH 49/67] Fix for specific molecule --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 12 +++++------- ...ListLeftVariableNumberedListAllTextAndLinks.swift | 5 +++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 35d45ac6..087e893c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -674,15 +674,9 @@ public typealias ActionBlock = () -> () setScale(scale) } - open override func layoutSubviews() { - super.layoutSubviews() - - // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. - preferredMaxLayoutWidth = frame.width - } - @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber + if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) @@ -881,6 +875,10 @@ extension Label { return true } + public func horizontalAlignment() -> UIStackView.Alignment { + return .leading + } + public func copyBackgroundColor() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index 9f2d62c9..f00e7ff1 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -58,4 +58,9 @@ import Foundation super.reset() leftLabel.styleTitle2XLarge(true) } + + open override func layoutSubviews() { + super.layoutSubviews() + eyebrowHeadlineBodyLink.body.preferredMaxLayoutWidth = eyebrowHeadlineBodyLink.frame.width + } } From 1588644577ab84502f869dc16fe25c0aa090403f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 16:28:05 -0400 Subject: [PATCH 50/67] comment --- .../ListLeftVariableNumberedListAllTextAndLinks.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index f00e7ff1..d623311b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -61,6 +61,7 @@ import Foundation open override func layoutSubviews() { super.layoutSubviews() + // This fixes a defect body text where it doesn't layout correctly. eyebrowHeadlineBodyLink.body.preferredMaxLayoutWidth = eyebrowHeadlineBodyLink.frame.width } } From eb195afe1d0a51ab38484caf5bdea9eae0ff11a8 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 22 May 2020 16:30:14 -0400 Subject: [PATCH 51/67] fix for 3.0 --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 6 +++--- MVMCoreUI/Styles/Styler.swift | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 087e893c..d47a374f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -402,11 +402,11 @@ public typealias ActionBlock = () -> () attributedString.insert(mutableString, at: imageAtt.location) case let fontAtt as LabelAttributeFontModel: - if let fontStyle = fontAtt.style?.rawValue { - let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) + if let fontStyle = fontAtt.style { attributedString.removeAttribute(.font, range: range) attributedString.removeAttribute(.foregroundColor, range: range) - attributedString.addAttributes(styles.attributes(at: 0, effectiveRange: nil), range: range) + attributedString.addAttribute(.font, value: fontStyle.getFont(), range: range) + attributedString.addAttribute(.foregroundColor, value: fontStyle.color(), range: range) } else { let fontSize = fontAtt.size var font: UIFont? diff --git a/MVMCoreUI/Styles/Styler.swift b/MVMCoreUI/Styles/Styler.swift index d8d0a519..43e4d319 100644 --- a/MVMCoreUI/Styles/Styler.swift +++ b/MVMCoreUI/Styles/Styler.swift @@ -81,6 +81,16 @@ open class Styler { } } + public func color() -> UIColor { + switch self { + case .B3: + return .mvmCoolGray6 + + default: + return .mvmBlack + } + } + /// Determines if the selected font case is bold or regular. public func isBold() -> Bool { From 428baa0012883f81736f2c410cda8b00704adc43 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:31:32 -0400 Subject: [PATCH 52/67] remove transparency, unused --- .../NavigationBar/NavigationItemModel.swift | 5 ---- .../NavigationItemModelProtocol.swift | 1 - MVMCoreUI/Categories/UIColor+Extension.swift | 25 ------------------- MVMCoreUI/Categories/UIColor+MFConvenience.h | 3 --- MVMCoreUI/Categories/UIColor+MFConvenience.m | 21 ---------------- .../Containers/NavigationController.swift | 4 +-- 6 files changed, 2 insertions(+), 57 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 38dee0d2..41a35182 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -16,7 +16,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public var title: String? public var hidden: Bool public var backgroundColor: Color? - public var translucent: Bool public var tintColor: Color public var line: LineModel? public var backButton: NavigationItemButtonModel? @@ -29,7 +28,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public init() { hidden = false - translucent = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) @@ -42,7 +40,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt case title case hidden case backgroundColor - case translucent case tintColor case line case backButton @@ -57,7 +54,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt title = try typeContainer.decodeIfPresent(String.self, forKey: .title) hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white) - translucent = try typeContainer.decodeIfPresent(Bool.self, forKey: .translucent) ?? false tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) @@ -72,7 +68,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt try container.encodeIfPresent(title, forKey: .title) try container.encode(hidden, forKey: .hidden) try container.encode(backgroundColor, forKey: .backgroundColor) - try container.encode(translucent, forKey: .translucent) try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) try container.encodeIfPresent(backButton, forKey: .backButton) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 634539d4..0bd192e3 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -12,7 +12,6 @@ public protocol NavigationItemModelProtocol { var title: String? { get set } var hidden: Bool { get set } var backgroundColor: Color? { get set } - var translucent: Bool { get set } var tintColor: Color { get set } var line: LineModel? { get set } var backButton: NavigationItemButtonModel? { get set } diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 1ef2e217..78be926d 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -269,31 +269,6 @@ extension UIColor { return .white } - public class func setBackgroundColor(_ color: UIColor, for navigationBar: UINavigationBar, isTransparent: Bool) { - - DispatchQueue.main.async { - - let view = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) - view.backgroundColor = color - - UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0) - - if let context = UIGraphicsGetCurrentContext() { - view.layer.render(in: context) - } - - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - if isTransparent { - navigationBar.setBackgroundImage(UIImage(), for: .default) - navigationBar.isTranslucent = false - } else { - navigationBar.setBackgroundImage(image, for: .default) - } - } - } - /// - parameter color: The UIColor intended to retrieve its hex value. public class func hexString(for color: UIColor) -> String? { diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.h b/MVMCoreUI/Categories/UIColor+MFConvenience.h index 92b28a36..97280ba1 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.h +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.h @@ -183,9 +183,6 @@ // Returns a gradient lighter color; + (nonnull UIColor *)mfGradientColor:(nullable UIColor *)color; -// Sets the background color for the nav bar. -+ (void)mfSetBackgroundColorForNavigationBar:(nonnull UIColor *)color navigationBar:(nonnull UINavigationBar *)navigationBar transparent:(BOOL)transparent; - #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color; diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index 33df3848..8786df01 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -389,27 +389,6 @@ return [UIColor whiteColor]; } - -+ (void)mfSetBackgroundColorForNavigationBar:(nonnull UIColor *)color navigationBar:(nonnull UINavigationBar *)navigationBar transparent:(BOOL)transparent { - - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)]; - view.backgroundColor = color; - UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); - [view.layer renderInContext:UIGraphicsGetCurrentContext()]; - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - if (transparent) { - [navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - [navigationBar setTranslucent:NO]; - - } else { - [navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault]; - - } - }]; -} - #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color { diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 3f7846a0..4367f2e1 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -18,7 +18,7 @@ import UIKit /// Provides MVM styling to the navigation bar. Returns a reference to the line. public static func style(_ navigationBar: UINavigationBar) -> Line { - UIColor.mfSetBackgroundColor(forNavigationBar: .white, navigationBar: navigationBar, transparent: false) + navigationBar.backgroundColor = .white navigationBar.shadowImage = UIImage() navigationBar.isOpaque = true navigationBar.tintColor = .black @@ -72,7 +72,7 @@ import UIKit viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil) navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) - UIColor.setBackgroundColor(navigationItemModel.backgroundColor?.uiColor ?? .white, for: navigationController.navigationBar, isTransparent: navigationItemModel.translucent) + navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white let tint = navigationItemModel.tintColor.uiColor navigationController.navigationBar.tintColor = tint From 4b9ea6a799d3bdcb42966cee3175457d980334c2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:36:21 -0400 Subject: [PATCH 53/67] adds background color to tabs --- .../Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index dc8b9cae..72773031 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -153,10 +153,11 @@ import UIKit override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) + backgroundColor = tabsModel?.backgroundColor?.uiColor self.delegateObject = delegateObject self.additionalData = additionalData - self.selectedIndex = tabsModel?.selectedIndex ?? 0 - self.bottomLine.backgroundColor = tabsModel?.selectedColor.uiColor + selectedIndex = tabsModel?.selectedIndex ?? 0 + bottomLine.backgroundColor = tabsModel?.selectedColor.uiColor reloadData() } } From 0efd49e6f4e68d1b0c32510ae0c5e96897339d27 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:37:10 -0400 Subject: [PATCH 54/67] color add --- .../Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 72773031..60b31225 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -237,13 +237,13 @@ extension Tabs: UICollectionViewDelegateFlowLayout { collect.selectItem(at: indexPath, animated: animated, scrollPosition: .centeredHorizontally) guard let tabCell = collect.cellForItem(at: indexPath) as? TabItemCell, let tabsModel = self.tabsModel else { return } - self.moveBottomLine(toIndex: indexPath, animated: animated, cell: tabCell) + moveBottomLine(toIndex: indexPath, animated: animated, cell: tabCell) tabCell.label.textColor = tabsModel.selectedColor.uiColor tabCell.updateAccessibility(indexPath: indexPath, selected: true, tabsModel: tabsModel) tabCell.setNeedsDisplay() tabCell.setNeedsLayout() tabCell.layoutIfNeeded() - self.delegate?.didSelectItem(indexPath, tabs: self) + delegate?.didSelectItem(indexPath, tabs: self) } } From ba0a748ad3d344ddbbd1dfcbf93844ba3177b962 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:38:57 -0400 Subject: [PATCH 55/67] remove duplicate --- MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 60b31225..8a6cb82d 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -153,7 +153,6 @@ import UIKit override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) - backgroundColor = tabsModel?.backgroundColor?.uiColor self.delegateObject = delegateObject self.additionalData = additionalData selectedIndex = tabsModel?.selectedIndex ?? 0 From e020a395745c9662f22dae7b11ca3b609f501f90 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 27 May 2020 09:56:22 -0400 Subject: [PATCH 56/67] corrections made --- MVMCoreUI/Atomic/Atoms/Views/Arrow.swift | 9 +++------ .../Views/CarouselIndicator/CarouselIndicator.swift | 9 +++------ MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift index 0a3e0457..a437f9d8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift @@ -42,15 +42,12 @@ open class Arrow: View { open var color: UIColor { get { - if let model = arrowModel, model.inverted { - return arrowModel?.color_inverted.uiColor ?? .mvmWhite - } else { - return arrowModel?.color.uiColor ?? .mvmBlack - } + guard let model = arrowModel else { return .mvmBlack } + return model.inverted ? model.color_inverted.uiColor : model.color.uiColor } set { if let model = arrowModel, model.inverted { - arrowModel?.color_inverted = Color(uiColor: newValue) + model.color_inverted = Color(uiColor: newValue) } else { arrowModel?.color = Color(uiColor: newValue) } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift index e202a212..6bff6e6b 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift @@ -79,15 +79,12 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { public var indicatorColor: UIColor { get { - if let model = carouselIndicatorModel, model.inverted { - return carouselIndicatorModel?.indicatorColor_inverted.uiColor ?? .mvmWhite - } else { - return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack - } + guard let model = carouselIndicatorModel else { return .mvmBlack } + return model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor } set { if let model = carouselIndicatorModel, model.inverted { - carouselIndicatorModel?.indicatorColor_inverted = Color(uiColor: newValue) + model.indicatorColor_inverted = Color(uiColor: newValue) } else { carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 8a245066..3189deab 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -106,7 +106,6 @@ import UIKit } if let backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted) { - self.backgroundColor_inverted = backgroundColor_inverted } @@ -121,6 +120,7 @@ import UIKit try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(backgroundColor_inverted, forKey: .backgroundColor_inverted) try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine) } } From 729a73a1a0f7ad94631477e30e7468c42eaf32a7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 10:51:23 -0400 Subject: [PATCH 57/67] remove panel from navigation setting. --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ---- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../NavigationBar/NavigationItemModel.swift | 12 +----------- .../PanelNavigationItemModelProtocol.swift | 14 -------------- MVMCoreUI/BaseControllers/ViewController.swift | 6 ++++-- MVMCoreUI/Containers/NavigationController.swift | 6 ------ 6 files changed, 6 insertions(+), 37 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 9079fc39..b532841b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -273,7 +273,6 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; - D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */; }; D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; @@ -699,7 +698,6 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; - D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; @@ -884,7 +882,6 @@ D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, - D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -2124,7 +2121,6 @@ 01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */, 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, - D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */, 94F6516D2437954100631BF9 /* Tabs.swift in Sources */, 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 18b3fee7..42b700ac 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -134,6 +134,7 @@ import Foundation // Other Molecules MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self) + try? ModelRegistry.register(NavigationItemModel.self) // Other Organisms MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 41a35182..b62bb399 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -8,7 +8,7 @@ import Foundation -public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationItemModelProtocol, MoleculeModelProtocol { +public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol { public class var identifier: String { return "navigationBar" } @@ -22,17 +22,11 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public var additionalLeftButtons: [NavigationItemButtonModel]? public var additionalRightButtons: [NavigationItemButtonModel]? - // Legacy, will remove once menu is gone. - public var showLeftPanelButton: Bool - public var showRightPanelButton: Bool - public init() { hidden = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) - showLeftPanelButton = true - showRightPanelButton = true backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel()) } @@ -57,8 +51,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) - showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton) ?? true - showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton) ?? true additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons) additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons) } @@ -71,8 +63,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) try container.encodeIfPresent(backButton, forKey: .backButton) - try container.encode(showLeftPanelButton, forKey: .showLeftPanelButton) - try container.encode(showRightPanelButton, forKey: .showRightPanelButton) try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons) } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift deleted file mode 100644 index 8f599be4..00000000 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// PanelNavigationItemModelProtocol.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 5/18/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - -public protocol PanelNavigationItemModelProtocol { - var showLeftPanelButton: Bool { get set } - var showRightPanelButton: Bool { get set } -} diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 782deae2..eb92dd85 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -163,8 +163,6 @@ import UIKit open func createDefaultLegacyNavigationModel() -> NavigationItemModel { let navigationModel = NavigationItemModel() navigationModel.title = pageModel?.screenHeading - navigationModel.showLeftPanelButton = isMasterInitiallyAccessible() - navigationModel.showRightPanelButton = isSupportInitiallyAccessible() if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true { navigationModel.line = LineModel(type: .none) } @@ -203,6 +201,10 @@ import UIKit showBottomProgressBar() } NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + + // TODO: Legacy Update Panels. Change how this is done. + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(isMasterInitiallyAccessible(), for: viewController) + MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(isSupportInitiallyAccessible(), for: viewController) } // Eventually will be moved to server diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 4367f2e1..0b2d1546 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -95,11 +95,5 @@ import UIKit // Update icons if main navigation controller. MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) - - // Update Panels - if let model = navigationItemModel as? PanelNavigationItemModelProtocol { - MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) - MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) - } } } From abbe26b4bdd3b3009feab63c0ea28535dba88582 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 14:05:48 -0400 Subject: [PATCH 58/67] Move enable able from button protocol added navigation button atoms and protocol. Changed the way split handles additional buttons --- MVMCoreUI.xcodeproj/project.pbxproj | 32 +++++++++++-- .../Atomic/Atoms/Buttons/ButtonModel.swift | 2 +- .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 2 +- .../Atomic/Atoms/Buttons/Link/LinkModel.swift | 2 +- .../Buttons/ImageBarButtonItem.swift | 45 +++++++++++++++++ .../Buttons/LabelBarButtonItem.swift | 44 +++++++++++++++++ .../NavigationButtomModelProtocol.swift | 15 ++++++ .../NavigationImageButtonModel.swift} | 11 +++-- .../Buttons/NavigationLabelButtonModel.swift | 44 +++++++++++++++++ .../NavigationBar/NavigationItemModel.swift | 20 ++++---- .../ModelProtocols/ButtonModelProtocol.swift | 2 +- .../NavigationItemModelProtocol.swift | 6 +-- MVMCoreUI/BaseClasses/BarButtonItem.swift | 40 ++-------------- MVMCoreUI/BaseClasses/Button.swift | 6 ++- .../BaseControllers/ViewController.swift | 22 +++++---- .../Containers/NavigationController.swift | 14 ++---- .../MVMCoreUISplitViewController.m | 48 +------------------ 17 files changed, 227 insertions(+), 128 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift rename MVMCoreUI/Atomic/Molecules/NavigationBar/{NavigationItemButtonModel.swift => Buttons/NavigationImageButtonModel.swift} (74%) create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b532841b..0ebd9799 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -274,9 +274,12 @@ D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; + D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; }; + D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; }; + D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; - D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; + D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; }; @@ -323,6 +326,7 @@ D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */; }; D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */; }; D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */; }; + D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; }; D29C94D5242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */; }; @@ -699,9 +703,12 @@ D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; + D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = ""; }; + D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = ""; }; + D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageBarButtonItem.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; - D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; + D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationImageButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; @@ -746,6 +753,7 @@ D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonViewModel.swift; sourceTree = ""; }; D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerLabelsModel.swift; sourceTree = ""; }; D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyCaretLinkImageModel.swift; sourceTree = ""; }; + D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtomModelProtocol.swift; sourceTree = ""; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = ""; }; D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = ""; }; D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUICommonViewsUtility+Extension.swift"; sourceTree = ""; }; @@ -1361,10 +1369,22 @@ path = TwoColumn; sourceTree = ""; }; + D23EA7FC247EBB7500D60C34 /* Buttons */ = { + isa = PBXGroup; + children = ( + D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */, + D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */, + D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */, + D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */, + D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */, + ); + path = Buttons; + sourceTree = ""; + }; D2509ED42472EE0B001BFB9D /* NavigationBar */ = { isa = PBXGroup; children = ( - D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */, + D23EA7FC247EBB7500D60C34 /* Buttons */, D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */, ); path = NavigationBar; @@ -1976,7 +1996,7 @@ 8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */, 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, - D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, + D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */, 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, @@ -2153,7 +2173,9 @@ BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */, D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */, 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */, + D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */, D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */, + D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */, 01EB368F23609801006832FA /* LabelModel.swift in Sources */, 0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */, AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */, @@ -2223,6 +2245,7 @@ BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, + D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */, 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */, AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */, @@ -2291,6 +2314,7 @@ 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, + D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */, D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */, 012A88F123985E0100FE3DA1 /* Color.swift in Sources */, D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index b0e4d54d..0881af71 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -11,7 +11,7 @@ import UIKit public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?) -public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol { +public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 5a4a4c14..a37baeca 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -10,7 +10,7 @@ import Foundation import MVMCore -public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { +public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index d51bddf4..bd1b601d 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -9,7 +9,7 @@ import UIKit -open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { +open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift new file mode 100644 index 00000000..564b9f42 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift @@ -0,0 +1,45 @@ +// +// ImageBarButtonItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ImageBarButtonItem: BarButtonItem { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + public static func create(with image: UIImage?) -> Self { + let actionObject = ActionDelegate() + let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionDelegate = actionObject + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: image) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: image) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { + let button = create(with: image) + button.actionDelegate?.buttonAction = action + return button + } +} + diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift new file mode 100644 index 00000000..4d31a84c --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift @@ -0,0 +1,44 @@ +// +// LabelBarButtonItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class LabelBarButtonItem: BarButtonItem { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + public static func create(with title: String?) -> Self { + let actionObject = ActionDelegate() + let button = self.init(title: title, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionDelegate = actionObject + return button + } + + /// Creates the item with the passed in action. + public static func create(with title: String?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: title) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with title: String?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: title) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with title: String?, action: @escaping BarButtonAction) -> Self { + let button = create(with: title) + button.actionDelegate?.buttonAction = action + return button + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift new file mode 100644 index 00000000..3f38ce43 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift @@ -0,0 +1,15 @@ +// +// NavigationButtomModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol NavigationButtomModelProtocol: ButtonModelProtocol { + //var color: Color? { get set } + + func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> BarButtonItem +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift similarity index 74% rename from MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift rename to MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index 26be6952..b4173e8b 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -7,9 +7,12 @@ import Foundation -public class NavigationItemButtonModel: Codable { - var imageName: String - var action: ActionModelProtocol +public class NavigationImageButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "navigationImageButton" + + public var imageName: String + public var action: ActionModelProtocol public init(with imageName: String, action: ActionModelProtocol) { self.imageName = imageName @@ -36,6 +39,6 @@ public class NavigationItemButtonModel: Codable { /// Convenience function that creates a BarButtonItem for the model. public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) - return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + return ImageBarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } } diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift new file mode 100644 index 00000000..6b253459 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -0,0 +1,44 @@ +// +// NavigationLabelButtonModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class NavigationLabelButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "navigationLabelButton" + + public var title: String + public var action: ActionModelProtocol + + public init(with title: String, action: ActionModelProtocol) { + self.title = title + self.action = action + } + + private enum CodingKeys: String, CodingKey { + case title + case action + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + title = try typeContainer.decode(String.self, forKey: .title) + action = try typeContainer.decodeModel(codingKey: .action) + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(title, forKey: .title) + try container.encodeModel(action, forKey: .action) + } + + /// Convenience function that creates a BarButtonItem for the model. + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + return LabelBarButtonItem.create(with: title, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index b62bb399..f29f1e38 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -18,16 +18,16 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt public var backgroundColor: Color? public var tintColor: Color public var line: LineModel? - public var backButton: NavigationItemButtonModel? - public var additionalLeftButtons: [NavigationItemButtonModel]? - public var additionalRightButtons: [NavigationItemButtonModel]? + public var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? + public var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? + public var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? public init() { hidden = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) - backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel()) + backButton = NavigationImageButtonModel(with: "back", action: ActionBackModel()) } private enum CodingKeys: String, CodingKey { @@ -50,9 +50,9 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white) tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) - backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) - additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons) - additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons) + backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton) ?? NavigationImageButtonModel(with: "back", action: ActionBackModel()) + additionalLeftButtons = try typeContainer.decodeModels(codingKey: .additionalLeftButtons) + additionalRightButtons = try typeContainer.decodeModels(codingKey: .additionalRightButtons) } open func encode(to encoder: Encoder) throws { @@ -62,8 +62,8 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt try container.encode(backgroundColor, forKey: .backgroundColor) try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) - try container.encodeIfPresent(backButton, forKey: .backButton) - try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) - try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons) + try container.encodeModelIfPresent(backButton, forKey: .backButton) + try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) + try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons) } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift index 1288f4e3..71c3b232 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift @@ -8,6 +8,6 @@ import Foundation -public protocol ButtonModelProtocol: EnableableModelProtocol { +public protocol ButtonModelProtocol { var action: ActionModelProtocol { get set } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 0bd192e3..e6491ac3 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -14,7 +14,7 @@ public protocol NavigationItemModelProtocol { var backgroundColor: Color? { get set } var tintColor: Color { get set } var line: LineModel? { get set } - var backButton: NavigationItemButtonModel? { get set } - var additionalLeftButtons: [NavigationItemButtonModel]? { get set } - var additionalRightButtons: [NavigationItemButtonModel]? { get set } + var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? { get set } + var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } + var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } } diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index ac26c040..f2da9c7c 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -8,9 +8,9 @@ public typealias BarButtonAction = (BarButtonItem) -> () -@objc fileprivate class ActionDelegate: NSObject { - fileprivate var buttonAction: BarButtonAction? - @objc fileprivate func callActionBlock(_ sender: BarButtonItem) { +@objc internal class ActionDelegate: NSObject { + internal var buttonAction: BarButtonAction? + @objc internal func callActionBlock(_ sender: BarButtonItem) { buttonAction?(sender) } } @@ -22,39 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - private var actionDelegate: ActionDelegate? - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - - public static func create(with image: UIImage?) -> Self { - let actionObject = ActionDelegate() - let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) - button.actionDelegate = actionObject - return button - } - - /// Creates the item with the passed in action. - public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = create(with: image) - button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) - return button - } - - /// Creates the item with the passed in action map. - public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = create(with: image) - button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) - return button - } - - /// Creates the item with the passed in action. - public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { - let button = create(with: image) - button.actionDelegate?.buttonAction = action - return button - } + internal var actionDelegate: ActionDelegate? //-------------------------------------------------- // MARK: - Methods diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index f4ab51c6..5d42c5fb 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -94,9 +94,11 @@ public typealias ButtonAction = (Button) -> () self.backgroundColor = backgroundColor.uiColor } - guard let model = model as? ButtonModelProtocol else { return } + if let model = model as? EnableableModelProtocol { + isEnabled = model.enabled + } - isEnabled = model.enabled + guard let model = model as? ButtonModelProtocol else { return } set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index eb92dd85..0e313ac8 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -189,22 +189,28 @@ import UIKit // MARK: - Navigation Item (Move to model base) open func setNavigationController() { + let viewController = manager ?? self guard let navigationItemModel = pageModel?.navigationItem, - let navigationController = manager?.navigationController ?? navigationController else { + let navigationController = viewController.navigationController else { MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() return } - let viewController = manager ?? self - if navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController { - MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels() - showBottomProgressBar() - } + + // We additionally want our left items + navigationItem.leftItemsSupplementBackButton = true + NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - // TODO: Legacy Update Panels. Change how this is done. + // Special logic when using the split view controller. Legacy Update Panels. Change how this is done. + guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, + navigationController.topViewController == viewController else { return } + + MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels() + showBottomProgressBar() + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(isMasterInitiallyAccessible(), for: viewController) MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(isSupportInitiallyAccessible(), for: viewController) + MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(navigationItemModel.tintColor.uiColor) } // Eventually will be moved to server diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 0b2d1546..ab57f9f8 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -84,16 +84,8 @@ import UIKit if let navigationController = navigationController as? NavigationController { navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none } - - // Let legacy splitview controller handle buttons for now. - guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController else { - // Not the main split view controller, add buttons. - setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - return - } - - // Update icons if main navigation controller. - MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + + // Sets up the navigation buttons. + setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index d9814a1f..0ce218b2 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -107,29 +107,12 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; } - UIViewController *controller = (UIViewController *)viewController; - NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]]; - if (!item) { return self.backButton; } - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; -} - - (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } - UIViewController *controller = (UIViewController *)viewController; - NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return viewController.navigationItem.leftBarButtonItems; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } - UIViewController *controller = (UIViewController *)viewController; - NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return viewController.navigationItem.rightBarButtonItems; } - (CGFloat)leftPanelExtendedWidth { @@ -251,15 +234,6 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; - if ([viewController.navigationController.viewControllers count] > 1) { - UIBarButtonItem *button = [self getBackButtonForViewController:viewController]; - if (button) { - viewController.navigationItem.hidesBackButton = YES; - [leftBarButtonItems addObject:button]; - } else { - viewController.navigationItem.hidesBackButton = NO; - } - } if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } @@ -625,24 +599,6 @@ CGFloat const PanelAnimationDuration = 0.2; #pragma mark - Other Panel Functions -/// Convenience function, creates a BarButtonItem from button json -- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; - BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil]; - return item; -} - -/// Convenience function, creates a list of BarButtonItems list of json -- (nullable NSArray *)createNavigationItemButtonsFrom:(nullable NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - if (JSONlist.count == 0) { return nil; } - NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; - for (NSDictionary *itemData in JSONlist) { - UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject]; - [items addObject:item]; - } - return items; -} - - (void)forceHideBothDrawers { [self hideBothDrawersShouldForceHide:YES]; } From 51b327a6d64a3f471b124c3bc3e4b95c9677c703 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 14:21:14 -0400 Subject: [PATCH 59/67] fixes for decoding --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 6 +++++- .../Buttons/NavigationButtomModelProtocol.swift | 4 ++-- .../Buttons/NavigationImageButtonModel.swift | 2 +- .../Buttons/NavigationLabelButtonModel.swift | 2 +- .../NavigationBar/NavigationItemModel.swift | 15 ++++++++------- .../NavigationItemModelProtocol.swift | 6 +++--- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 42b700ac..b968cecc 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -134,8 +134,12 @@ import Foundation // Other Molecules MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self) - try? ModelRegistry.register(NavigationItemModel.self) + // Navigation Molecules + try? ModelRegistry.register(NavigationItemModel.self) + try? ModelRegistry.register(NavigationImageButtonModel.self) + try? ModelRegistry.register(NavigationLabelButtonModel.self) + // Other Organisms MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self) MoleculeObjectMapping.shared()?.register(viewClass: BarsIndicatorView.self, viewModelClass: BarsCarouselIndicatorModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift index 3f38ce43..057f2bf5 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift @@ -1,5 +1,5 @@ // -// NavigationButtomModelProtocol.swift +// NavigationButtonModelProtocol.swift // MVMCoreUI // // Created by Scott Pfeil on 5/27/20. @@ -8,7 +8,7 @@ import Foundation -public protocol NavigationButtomModelProtocol: ButtonModelProtocol { +public protocol NavigationButtonModelProtocol: ButtonModelProtocol { //var color: Color? { get set } func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> BarButtonItem diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index b4173e8b..be820ec9 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -7,7 +7,7 @@ import Foundation -public class NavigationImageButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { +public class NavigationImageButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol { public var backgroundColor: Color? public static var identifier: String = "navigationImageButton" diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift index 6b253459..699b1ed0 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -8,7 +8,7 @@ import Foundation -public class NavigationLabelButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { +public class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol { public var backgroundColor: Color? public static var identifier: String = "navigationLabelButton" diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index f29f1e38..05aec0a3 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -18,16 +18,15 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt public var backgroundColor: Color? public var tintColor: Color public var line: LineModel? - public var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? - public var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? - public var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? + public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "back", action: ActionBackModel()) + public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? + public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? public init() { hidden = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) - backButton = NavigationImageButtonModel(with: "back", action: ActionBackModel()) } private enum CodingKeys: String, CodingKey { @@ -50,9 +49,11 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white) tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) - backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton) ?? NavigationImageButtonModel(with: "back", action: ActionBackModel()) - additionalLeftButtons = try typeContainer.decodeModels(codingKey: .additionalLeftButtons) - additionalRightButtons = try typeContainer.decodeModels(codingKey: .additionalRightButtons) + if let backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol) = try typeContainer.decodeModelIfPresent(codingKey: .backButton) { + self.backButton = backButton + } + additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons) + additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons) } open func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index e6491ac3..e4017428 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -14,7 +14,7 @@ public protocol NavigationItemModelProtocol { var backgroundColor: Color? { get set } var tintColor: Color { get set } var line: LineModel? { get set } - var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? { get set } - var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } - var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } + var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set } + var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set } + var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set } } From 27e7235e0b6f65e15b52a34671d7621d94b73796 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 14:39:57 -0400 Subject: [PATCH 60/67] fixes for navigation item setter --- MVMCoreUI/Containers/NavigationController.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index ab57f9f8..6f3bf06f 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -46,23 +46,25 @@ import UIKit /// Convenience function for setting the navigation buttons. public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject - var items: [UIBarButtonItem] = [] + var leftItems: [UIBarButtonItem] = [] if let backButtonModel = navigationItemModel.backButton, navigationController.viewControllers.count > 1 { - items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let leftItemModels = navigationItemModel.additionalLeftButtons { for item in leftItemModels { - items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } - viewController.navigationItem.leftBarButtonItems = items } + viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil + + var rightItems: [UIBarButtonItem] = [] if let rightItemModels = navigationItemModel.additionalRightButtons { for item in rightItemModels { - items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } - viewController.navigationItem.rightBarButtonItems = items } + viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil } /// Convenience function for setting navigation bar with model. From db3f8a5becd62892407672f82f0930dabbb2395e Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 14:45:35 -0400 Subject: [PATCH 61/67] ordering of left buttons --- .../SplitViewController/MVMCoreUISplitViewController.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 0ce218b2..414895dc 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -234,13 +234,13 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; - if ((accessible && !extended) && self.leftPanelButton) { - [leftBarButtonItems addObject:self.leftPanelButton]; - } NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController]; if (extraButtons) { [leftBarButtonItems addObjectsFromArray:extraButtons]; } + if ((accessible && !extended) && self.leftPanelButton) { + [leftBarButtonItems addObject:self.leftPanelButton]; + } [viewController.navigationItem setLeftBarButtonItems:(leftBarButtonItems.count > 0 ? leftBarButtonItems : nil) animated:!DisableAnimations]; } From 632f6a825c88b13fc7d7cd30013963cb49f86da2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 15:58:31 -0400 Subject: [PATCH 62/67] comment --- .../NavigationBar/Buttons/NavigationButtomModelProtocol.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift index 057f2bf5..e43f4664 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift @@ -9,6 +9,7 @@ import Foundation public protocol NavigationButtonModelProtocol: ButtonModelProtocol { + // TODO: add color setting to models and items //var color: Color? { get set } func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> BarButtonItem From f2498a53f9a2446840e748ca4dfd6989a198998d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 16:00:46 -0400 Subject: [PATCH 63/67] comment --- .../NavigationBar/Buttons/NavigationButtomModelProtocol.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift index e43f4664..50870172 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift @@ -12,5 +12,6 @@ public protocol NavigationButtonModelProtocol: ButtonModelProtocol { // TODO: add color setting to models and items //var color: Color? { get set } - func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> BarButtonItem + /// Returns a bar button item created using data from the model. + func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UIBarButtonItem } From bf6a81f367a252556aeac645004b440d9789c004 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 16:12:43 -0400 Subject: [PATCH 64/67] remove excess internal --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index f2da9c7c..cbb6ba2d 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -8,9 +8,9 @@ public typealias BarButtonAction = (BarButtonItem) -> () -@objc internal class ActionDelegate: NSObject { - internal var buttonAction: BarButtonAction? - @objc internal func callActionBlock(_ sender: BarButtonItem) { +@objc class ActionDelegate: NSObject { + var buttonAction: BarButtonAction? + @objc func callActionBlock(_ sender: BarButtonItem) { buttonAction?(sender) } } @@ -22,7 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - internal var actionDelegate: ActionDelegate? + var actionDelegate: ActionDelegate? //-------------------------------------------------- // MARK: - Methods From 336a0bb98356b9cf0b0eb3a355a6f72fa5fa4bc4 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 16:13:20 -0400 Subject: [PATCH 65/67] fix return type --- .../NavigationBar/Buttons/NavigationImageButtonModel.swift | 2 +- .../NavigationBar/Buttons/NavigationLabelButtonModel.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index be820ec9..aff9c58f 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -37,7 +37,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule } /// Convenience function that creates a BarButtonItem for the model. - public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem { let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) return ImageBarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift index 699b1ed0..e113c1f6 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -38,7 +38,7 @@ public class NavigationLabelButtonModel: NavigationButtonModelProtocol, Molecule } /// Convenience function that creates a BarButtonItem for the model. - public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem { return LabelBarButtonItem.create(with: title, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } } From 4be261e3184656d61b10025df83b91777a51062d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 17:37:17 -0400 Subject: [PATCH 66/67] update to match documentation --- .../Protocols/ModelProtocols/PageModelProtocol.swift | 2 +- MVMCoreUI/Atomic/Templates/TemplateModel.swift | 8 ++++---- MVMCoreUI/BaseControllers/ViewController.swift | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift index ec2bead8..275b17a1 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift @@ -13,5 +13,5 @@ public protocol PageModelProtocol { /// Temporary: for legacy response var screenHeading: String? { get set } var backgroundColor: Color? { get set } - var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set } + var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set } } diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/TemplateModel.swift index e8992e58..b478167d 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/TemplateModel.swift @@ -26,7 +26,7 @@ import Foundation public var backgroundColor: Color? public var screenHeading: String? - public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? + public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? public var formRules: [FormGroupRule]? public var behaviors: [PageBehaviorProtocol]? @@ -49,7 +49,7 @@ import Foundation case backgroundColor case formRules case behaviors - case navigationItem + case navigationBar } //-------------------------------------------------- @@ -63,7 +63,7 @@ import Foundation backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) behaviors = try typeContainer.decodeModelsIfPresent(codingKey: .behaviors) - navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem) + navigationBar = try typeContainer.decodeModelIfPresent(codingKey: .navigationBar) } public func encode(to encoder: Encoder) throws { @@ -73,6 +73,6 @@ import Foundation try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(screenHeading, forKey: .screenHeading) try container.encodeIfPresent(formRules, forKey: .formRules) - try container.encodeModelIfPresent(navigationItem, forKey: .navigationItem) + try container.encodeModelIfPresent(navigationBar, forKey: .navigationBar) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 0e313ac8..6ec63c24 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -172,9 +172,9 @@ import UIKit /// Processes any new data. Called after the page is loaded the first time and on response updates for this page, open func handleNewData() { // TODO: remove legacy. Temporary, convert legacy to navigation model. - if pageModel?.navigationItem == nil { + if pageModel?.navigationBar == nil { let navigationItem = createDefaultLegacyNavigationModel() - pageModel?.navigationItem = navigationItem + pageModel?.navigationBar = navigationItem } if formValidator == nil { @@ -190,7 +190,7 @@ import UIKit // MARK: - Navigation Item (Move to model base) open func setNavigationController() { let viewController = manager ?? self - guard let navigationItemModel = pageModel?.navigationItem, + guard let navigationItemModel = pageModel?.navigationBar, let navigationController = viewController.navigationController else { MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() return From 50a87cd864155d3b6c07d9d4ed1592c593bc64e2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 May 2020 18:35:05 -0400 Subject: [PATCH 67/67] code simplification --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++-- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 +- ...ftVariableIconWithRightCaretBodyText.swift | 24 +++++-------------- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index c6f97754..f44a799d 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1306,14 +1306,14 @@ 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */, 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, + AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */, + AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */, 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */, 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */, AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */, AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */, 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */, 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */, - AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */, - AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */, ); path = LeftVariable; sourceTree = ""; diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index b4819234..89949f4a 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -142,12 +142,12 @@ import Foundation // Designed List Items MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift index 626d9c19..d05fea10 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift @@ -13,18 +13,16 @@ import Foundation //------------------------------------------------------- public let leftImage = LoadImageView() public let headlineBody = HeadlineBody() - public let rightLabel = Label.commonLabelB2(true) - private let rightLabelStackItem: StackItem + public let rightLabel = Label.createLabelRegularBodySmall(true) public var stack: Stack //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - rightLabelStackItem = StackItem(andContain: rightLabel) - let stackItems = [StackItem(andContain: leftImage), StackItem(andContain: headlineBody), rightLabelStackItem] - let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill), StackItemModel(spacing: 4, horizontalAlignment: .trailing)], axis: .horizontal) - stack = Stack(with: stackModel, stackItems: stackItems) + stack = Stack.createStack(with: [(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), + (view: headlineBody, model: StackItemModel(horizontalAlignment: .leading)), + (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -32,16 +30,6 @@ import Foundation fatalError("init(coder:) has not been implemented") } - open override func alignAccessoryToHero() -> CGPoint? { - // Ensures that the right label is centered vertically with headline. - let heroCenter = super.alignAccessoryToHero() - if let heroCenter = heroCenter { - let convertedPoint = stack.convert(heroCenter, from: self) - rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY - } - return heroCenter - } - //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- @@ -61,7 +49,7 @@ import Foundation //------------------------------------------------------ open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? ListLeftVariableIconWithRightCaretBodyTextModel else { return} + guard let model = model as? ListLeftVariableIconWithRightCaretBodyTextModel else { return } leftImage.set(with: model.image, delegateObject, additionalData) headlineBody.set(with: model.headlineBody, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData) @@ -73,6 +61,6 @@ import Foundation open override func reset() { super.reset() - rightLabel.styleB2(true) + rightLabel.styleRegularBodySmall(true) } }