From ba8058ccebe76cbb0f363ec759f6ffe31d22324f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Jan 2020 12:58:51 -0500 Subject: [PATCH 01/29] button swift --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 8 +- MVMCoreUI/Atoms/Buttons/Link.swift | 2 +- MVMCoreUI/Atoms/Buttons/PillButton.swift | 132 ++++++++++++++++++ MVMCoreUI/BaseClasses/Button.swift | 4 + .../BaseClasses/ButtonModelProtocol.swift | 14 ++ .../Buttons => Legacy/Views}/ButtonView.swift | 0 .../DisableableModelProtocol.swift | 13 ++ .../Items/DropDownFilterTableViewCell.swift | 2 +- .../OtherHandlers/MoleculeObjectMapping.swift | 2 +- 10 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 MVMCoreUI/Atoms/Buttons/PillButton.swift create mode 100644 MVMCoreUI/BaseClasses/ButtonModelProtocol.swift rename MVMCoreUI/{Atoms/Buttons => Legacy/Views}/ButtonView.swift (100%) create mode 100644 MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 410cf3c5..c5b03e04 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -313,6 +313,9 @@ D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */; }; D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */; }; D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */; }; + D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99E23E07F8A000B42E6 /* PillButton.swift */; }; + D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */; }; + D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */; }; D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; }; D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */; }; DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; }; @@ -633,6 +636,9 @@ D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImageModel.swift; sourceTree = ""; }; D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButtonModel.swift; sourceTree = ""; }; D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHeadlineBodyModel.swift; sourceTree = ""; }; + D2E2A99E23E07F8A000B42E6 /* PillButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = ""; }; + D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModelProtocol.swift; sourceTree = ""; }; + D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableableModelProtocol.swift; sourceTree = ""; }; D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = ""; }; D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackItem.swift; sourceTree = ""; }; @@ -668,6 +674,7 @@ 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */, D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */, 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */, + D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -816,6 +823,7 @@ D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, + D282AACA2243C61700C46919 /* ButtonView.swift */, ); path = Views; sourceTree = ""; @@ -1144,11 +1152,11 @@ 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */, DBC4391A224421A0001AB423 /* CaretButton.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, - D282AACA2243C61700C46919 /* ButtonView.swift */, + D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, + C07065C32395677300FBF997 /* Link.swift */, D28A838C23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift */, D28A837623C79FC600DFE4FC /* MFCustomButton+ActionModel.swift */, - C07065C32395677300FBF997 /* Link.swift */, ); path = Buttons; sourceTree = ""; @@ -1346,6 +1354,7 @@ D2B18B7D236090D500A9AEDC /* BaseClasses */ = { isa = PBXGroup; children = ( + D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */, C003506023AA94CD00B6AC29 /* Button.swift */, D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, @@ -1559,6 +1568,7 @@ D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */, + D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */, D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */, D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, @@ -1574,6 +1584,7 @@ 014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */, D260106123D0C02A00764D80 /* StackItemModelProtocol.swift in Sources */, 012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */, + D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */, 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */, D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, @@ -1705,6 +1716,7 @@ D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, + D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 61e3ca3e..ce513a03 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -18,12 +18,13 @@ public enum ButtonSize: String, Codable { case tiny } -public class ButtonModel: MoleculeModelProtocol { +public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public static var identifier: String = "button" public var moleculeName: String? public var backgroundColor: Color? public var title: String public var action: ActionModelProtocol + public var enabled: Bool = true public var style: ButtonStyle? public var size: ButtonSize? = .standard public var required: Bool? @@ -39,6 +40,7 @@ public class ButtonModel: MoleculeModelProtocol { case backgroundColor case title case action + case enabled case style case size case required @@ -60,6 +62,9 @@ public class ButtonModel: MoleculeModelProtocol { if let size = try typeContainer.decodeIfPresent(ButtonSize.self, forKey: .size) { self.size = size } + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } } public func encode(to encoder: Encoder) throws { @@ -68,6 +73,7 @@ public class ButtonModel: MoleculeModelProtocol { try container.encode(title, forKey: .title) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModel(action, forKey: .action) + try container.encode(enabled, forKey: .enabled) try container.encodeIfPresent(style, forKey: .style) try container.encodeIfPresent(size, forKey: .size) try container.encodeIfPresent(required, forKey: .required) diff --git a/MVMCoreUI/Atoms/Buttons/Link.swift b/MVMCoreUI/Atoms/Buttons/Link.swift index 8cb9bb49..b4c00c94 100644 --- a/MVMCoreUI/Atoms/Buttons/Link.swift +++ b/MVMCoreUI/Atoms/Buttons/Link.swift @@ -46,7 +46,7 @@ import UIKit set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } - public static func estimatedHeight(forRow molecule: ModuleMoleculeModel?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 31.0 } } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift new file mode 100644 index 00000000..6cf21c40 --- /dev/null +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -0,0 +1,132 @@ +// +// PillButton.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 1/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class PillButton: Button { + var size = MVMCoreUIUtility.getWidth() + var buttonModel: ButtonModel? { + get { return model as? ButtonModel } + } + + open override var isEnabled: Bool { + didSet { + style() + } + } + + public func stylePrimary() { + setTitleColor(.white, for: .normal) + setTitleColor(.white, for: .disabled) + layer.borderWidth = 0; + if isEnabled { + backgroundColor = .black + } else { + backgroundColor = .mvmCoolGray6 + } + } + + public func styleSecondary() { + setTitleColor(.black, for: .normal) + setTitleColor(.mvmCoolGray6, for: .disabled) + backgroundColor = .clear + layer.borderWidth = 1; + if isEnabled { + layer.borderColor = UIColor.black.cgColor + } else { + layer.borderColor = UIColor.mvmCoolGray6.cgColor + } + } + + private func style() { + guard let model = buttonModel else { return } + if let style = model.style { + switch style { + case .primary: + stylePrimary() + case .secondary: + styleSecondary() + } + } + } + + private func getInnerPadding() -> CGFloat { + return (getHeight() / 2.0) + } + + private func getHeight() -> CGFloat { + PillButton.getHeight(for: (model as? ButtonModel)?.size, size: size) + } + + public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { + switch buttonSize { + case .tiny: + return MFSizeObject(standardSize: 20, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20 + default: + return MFSizeObject(standardSize: 42, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42 + } + } + + private func getMinimumWidth() -> CGFloat { + switch buttonModel?.size ?? .standard { + case .tiny: + return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0 + default: + return MFSizeObject(standardSize: 102.0, standardiPadPortraitSize: 136.0, iPadProLandscapeSize: 153.0)?.getValueBased(onSize: size) ?? 102.0 + } + } + + open override var intrinsicContentSize: CGSize { + let size = super.intrinsicContentSize + let width = size.width + (2 * getInnerPadding()) + return CGSize(width: max(width, getMinimumWidth()), height: getHeight()) + } + + // MARK: - ModelMoleculeViewProtocol + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? ButtonModel else { return } + setTitle(model.title, for: .normal) + + /*self.validationRequired = model.required ?? false + self.requiredGroupsList = model.requiredGroups + + if self.validationRequired, + let selfForm = self as? FormValidationEnableDisableProtocol { + FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) + }*/ + style() + } + + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + PillButton.getHeight(for: (molecule as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth()) + } + + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + self.size = size + invalidateIntrinsicContentSize() + titleLabel?.font = MFStyler.fontB1(forWidth: size) + self.layer.cornerRadius = getInnerPadding() + } + + open override func setupView() { + super.setupView() + titleLabel?.numberOfLines = 1 + titleLabel?.lineBreakMode = .byTruncatingTail + titleLabel?.textAlignment = .center + contentHorizontalAlignment = .center + stylePrimary() + } + + // MARK: - MVMCoreUIViewConstrainingProtocol + open func horizontalAlignment() -> UIStackView.Alignment { + return .center + } +} diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index 0a382705..a780151a 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -91,6 +91,10 @@ public typealias ButtonAction = (Button) -> () if let backgroundColor = model?.backgroundColor { self.backgroundColor = backgroundColor.uiColor } + + guard let model = model as? ButtonModelProtocol else { return } + isEnabled = model.enabled + set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } open class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { diff --git a/MVMCoreUI/BaseClasses/ButtonModelProtocol.swift b/MVMCoreUI/BaseClasses/ButtonModelProtocol.swift new file mode 100644 index 00000000..d16c2464 --- /dev/null +++ b/MVMCoreUI/BaseClasses/ButtonModelProtocol.swift @@ -0,0 +1,14 @@ +// +// ButtonModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 1/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol ButtonModelProtocol: EnableableModelProtocol { + var enabled: Bool { get set } + var action: ActionModelProtocol { get set } +} diff --git a/MVMCoreUI/Atoms/Buttons/ButtonView.swift b/MVMCoreUI/Legacy/Views/ButtonView.swift similarity index 100% rename from MVMCoreUI/Atoms/Buttons/ButtonView.swift rename to MVMCoreUI/Legacy/Views/ButtonView.swift diff --git a/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift new file mode 100644 index 00000000..1e49bd8c --- /dev/null +++ b/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift @@ -0,0 +1,13 @@ +// +// EnableableModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 1/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol EnableableModelProtocol { + var enabled: Bool { get set } +} diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 46139a37..8c813d24 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -60,7 +60,7 @@ import UIKit bottomSeparatorView?.setStyle(.none) } - public override static func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 80 } } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 34b8e6ca..71331e73 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -27,7 +27,7 @@ import Foundation ModelRegistry.register(LabelAttributeActionModel.self) // Buttons - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PrimaryButton.self, viewModelClass: ButtonModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretButton.self, viewModelClass: CaretLinkModel.self) From c0ca81c5685c3b06958b2b3a9b02b3d3cc0e111c Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Jan 2020 13:55:55 -0500 Subject: [PATCH 02/29] Pill button --- MVMCoreUI/Atoms/Buttons/PillButton.swift | 38 ++++++++++++++---------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 6cf21c40..8bda4b20 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -8,7 +8,7 @@ import UIKit -open class PillButton: Button { +open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { var size = MVMCoreUIUtility.getWidth() var buttonModel: ButtonModel? { get { return model as? ButtonModel } @@ -20,6 +20,11 @@ open class PillButton: Button { } } + private enum ButtonHeight: CGFloat { + case tiny = 20 + case standard = 42 + } + public func stylePrimary() { setTitleColor(.white, for: .normal) setTitleColor(.white, for: .disabled) @@ -44,14 +49,11 @@ open class PillButton: Button { } private func style() { - guard let model = buttonModel else { return } - if let style = model.style { - switch style { - case .primary: - stylePrimary() - case .secondary: - styleSecondary() - } + switch buttonModel?.style { + case .secondary: + styleSecondary() + default: + stylePrimary() } } @@ -66,9 +68,9 @@ open class PillButton: Button { public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { switch buttonSize { case .tiny: - return MFSizeObject(standardSize: 20, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20 + return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20 default: - return MFSizeObject(standardSize: 42, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42 + return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42 } } @@ -89,10 +91,12 @@ open class PillButton: Button { // MARK: - ModelMoleculeViewProtocol open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + // The button will get styled in the enable check in super. super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? ButtonModel else { return } setTitle(model.title, for: .normal) - + /*self.validationRequired = model.required ?? false self.requiredGroupsList = model.requiredGroups @@ -100,7 +104,6 @@ open class PillButton: Button { let selfForm = self as? FormValidationEnableDisableProtocol { FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) }*/ - style() } open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -112,8 +115,13 @@ open class PillButton: Button { super.updateView(size) self.size = size invalidateIntrinsicContentSize() - titleLabel?.font = MFStyler.fontB1(forWidth: size) - self.layer.cornerRadius = getInnerPadding() + switch buttonModel?.size { + case .tiny: + titleLabel?.font = MFFonts.mfFont75Bd(11 * (intrinsicContentSize.height / ButtonHeight.tiny.rawValue)) + default: + titleLabel?.font = MFFonts.mfFont75Bd(13 * (intrinsicContentSize.height / ButtonHeight.standard.rawValue)) + } + layer.cornerRadius = getInnerPadding() } open override func setupView() { From 2ebce1b93b1f8d0a43462c1062199f61f9e9f3d1 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Jan 2020 14:04:56 -0500 Subject: [PATCH 03/29] swift button --- MVMCoreUI/Atoms/Buttons/PillButton.swift | 32 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 8bda4b20..fc752f7a 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -8,12 +8,15 @@ import UIKit -open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { +open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidationEnableDisableProtocol { + // Used to size the button. var size = MVMCoreUIUtility.getWidth() + var buttonModel: ButtonModel? { get { return model as? ButtonModel } } + // Need to re-style on set. open override var isEnabled: Bool { didSet { style() @@ -25,6 +28,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { case standard = 42 } + /// The primary styling for a button. Should be used for main buttons public func stylePrimary() { setTitleColor(.white, for: .normal) setTitleColor(.white, for: .disabled) @@ -36,6 +40,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { } } + /// The secondary styling for a button. Should be used for secondary buttons public func styleSecondary() { setTitleColor(.black, for: .normal) setTitleColor(.mvmCoolGray6, for: .disabled) @@ -48,6 +53,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { } } + /// Styles the button based on the model style private func style() { switch buttonModel?.style { case .secondary: @@ -97,13 +103,10 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { guard let model = model as? ButtonModel else { return } setTitle(model.title, for: .normal) - /*self.validationRequired = model.required ?? false - self.requiredGroupsList = model.requiredGroups - - if self.validationRequired, - let selfForm = self as? FormValidationEnableDisableProtocol { - FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) - }*/ + if let required = model.required, + required == true { + FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) + } } open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -137,4 +140,17 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { open func horizontalAlignment() -> UIStackView.Alignment { return .center } + + // MARK: - FormValidationEnableDisableProtocol + public func isValidationRequired() -> Bool { + return buttonModel?.required ?? false + } + + public func requiredGroups() -> [String]? { + return buttonModel?.requiredGroups + } + + public func enableField(_ enable: Bool) { + isEnabled = isValidationRequired() ? enable : true + } } From ad8d18eabe572614ce630ff84650ec21369520c1 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 29 Jan 2020 09:17:36 -0500 Subject: [PATCH 04/29] buttonmodelprotocol --- MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift | 4 ++-- MVMCoreUI/Atoms/Buttons/LinkModel.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift index 04b5aa07..defe6816 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift @@ -9,14 +9,14 @@ import Foundation import MVMCore -public class CaretLinkModel: MoleculeModelProtocol { +public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { 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 disabledColor: Color? = Color(uiColor: .mfSilver()) - public var enabled: Bool = true + public var enabled = true public init(title: String, action: ActionModelProtocol) { self.title = title diff --git a/MVMCoreUI/Atoms/Buttons/LinkModel.swift b/MVMCoreUI/Atoms/Buttons/LinkModel.swift index 28e00d60..f4fab34c 100644 --- a/MVMCoreUI/Atoms/Buttons/LinkModel.swift +++ b/MVMCoreUI/Atoms/Buttons/LinkModel.swift @@ -8,7 +8,7 @@ import UIKit -public class LinkModel: MoleculeModelProtocol { +public class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { public static var identifier: String = "link" public var backgroundColor: Color? public var title: String From e6ae064c440f8f59b8f402a38c709ddf9ddb9e2e Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Wed, 29 Jan 2020 10:30:01 -0500 Subject: [PATCH 05/29] add PrimaryButtonView back into legacy view and view controller --- MVMCoreUI.xcodeproj/project.pbxproj | 8 + ...abelsAndBottomButtonsTableViewController.m | 15 +- .../TopLabelsAndBottomButtonsViewController.m | 13 +- MVMCoreUI/MVMCoreUI.h | 1 + .../PrimaryButtonView.h | 61 +++ .../PrimaryButtonView.m | 383 ++++++++++++++++++ 6 files changed, 468 insertions(+), 13 deletions(-) create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 410cf3c5..5e7467d9 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -115,6 +115,8 @@ 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */; }; 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */; }; 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B33239813C50067DD0F /* UIColor+Extension.swift */; }; + 94F217B623E0BF6100A47C06 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */; }; 94FB966223D797DA003D482B /* MFTextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94FB966023D797DA003D482B /* MFTextButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 94FB966323D797DA003D482B /* MFTextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94FB966123D797DA003D482B /* MFTextButton.m */; }; C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; @@ -422,6 +424,8 @@ 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeColorModel.swift; sourceTree = ""; }; 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeImageModel.swift; sourceTree = ""; }; 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeActionModel.swift; sourceTree = ""; }; + 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrimaryButtonView.h; sourceTree = ""; }; + 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrimaryButtonView.m; sourceTree = ""; }; 94FB966023D797DA003D482B /* MFTextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTextButton.h; sourceTree = ""; }; 94FB966123D797DA003D482B /* MFTextButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTextButton.m; sourceTree = ""; }; C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; @@ -859,6 +863,8 @@ D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */, D28A837E23CCA96400DFE4FC /* TabsModel.swift */, + 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, + 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, ); path = HorizontalCombinationViews; sourceTree = ""; @@ -1423,6 +1429,7 @@ D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */, D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */, D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */, + 94F217B623E0BF6100A47C06 /* PrimaryButtonView.h in Headers */, D29DF32021ED0CBA003B2FB9 /* LabelView.h in Headers */, D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */, D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */, @@ -1608,6 +1615,7 @@ D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, 0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */, + 94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */, 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */, 0A21DB8B235E06EF00C160A2 /* MFDigitTextBox.m in Sources */, D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */, diff --git a/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsTableViewController.m b/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsTableViewController.m index db1b7e5a..ac2ced97 100644 --- a/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsTableViewController.m +++ b/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsTableViewController.m @@ -7,6 +7,7 @@ // #import "TopLabelsAndBottomButtonsTableViewController.h" +#import #import #import #import @@ -121,7 +122,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary delegateObject:[self delegateObject] additionalData:nil]; + PrimaryButtonView *buttonView = [[PrimaryButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; @@ -439,16 +440,16 @@ - (void)setPrimaryLeftButtonHidden:(BOOL)left rightButtonHidden:(BOOL)right { - if ([self.bottomView isKindOfClass:[TwoButtonView class]]) { - TwoButtonView *buttonView = (TwoButtonView *)self.bottomView; + if ([self.bottomView isKindOfClass:[PrimaryButtonView class]]) { + PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; if (right && !left) { - [buttonView hideRightButton]; + [buttonView hidePrimaryRightButton]; } else if (!right && left) { - [buttonView hideLeftButton]; + [buttonView hidePrimaryLeftButton]; } else if (right && left) { - [buttonView hideBothButtons]; + [buttonView hideBothPrimaryButtons]; } else if (!right && !left) { - [buttonView showBothButtons]; + [buttonView showBothPrimaryButtons]; } } } diff --git a/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsViewController.m b/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsViewController.m index 95c0e26e..5998c5da 100644 --- a/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsViewController.m +++ b/MVMCoreUI/Legacy/Controllers/TopLabelsAndBottomButtonsViewController.m @@ -7,6 +7,7 @@ // #import "TopLabelsAndBottomButtonsViewController.h" +#import #import #import #import @@ -81,18 +82,18 @@ } if (!self.customBottemView) { - TwoButtonView *buttonView = (TwoButtonView *)self.bottomView; + PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; if (self.secondaryButton || self.primaryButton) { UIEdgeInsets paddingForBottomButtons = [self paddingForBottomButtons]; - [buttonView setLeftPinConstant:paddingForBottomButtons.left]; - [buttonView setRightPinConstant:paddingForBottomButtons.right]; + buttonView.leftPin.constant = paddingForBottomButtons.left; + buttonView.rightPin.constant = paddingForBottomButtons.right; buttonView.topPin.constant = paddingForBottomButtons.top; buttonView.bottomPin.constant = paddingForBottomButtons.bottom; } else { buttonView.topPin.constant = 0; buttonView.bottomPin.constant = 0; - [buttonView setLeftPinConstant:0]; - [buttonView setRightPinConstant:0]; + buttonView.leftPin.constant = 0; + buttonView.rightPin.constant = 0; } } } @@ -138,7 +139,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary delegateObject:[self delegateObject] additionalData:nil]; + PrimaryButtonView *buttonView = [[PrimaryButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; bottomView = buttonView; diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index a71be907..9150e015 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -88,6 +88,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import #pragma mark TextFields #import diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h new file mode 100644 index 00000000..c0e8994d --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h @@ -0,0 +1,61 @@ +// +// PrimaryButtonView.h +// myverizon +// +// Created by Scott Pfeil on 12/11/15. +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + +#import +#import +#import + +@interface PrimaryButtonView : ViewConstrainingView + +// Set when there is one button or it is the right button when there are two. +@property (nullable, weak, nonatomic) PrimaryButton *primaryButton; + +// The left button when there are two buttons. +@property (nullable, weak, nonatomic) PrimaryButton *secondaryButton; + +// Inits with a single button. +- (nonnull instancetype)initButtonSmall:(BOOL)small enabled:(BOOL)enabled; + +// Inits with two buttons. +- (nonnull instancetype)initWithTwoButtons; + +// Legacy: Sets up with whatever is in the passed in button map. (could be 0, 1, or 2 buttons) +- (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate; +- (nonnull instancetype)initWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate; +- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate; +- (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate; + +// Sets up with two buttons. +- (void)setupWithTwoButtons; + +// For subclassing, just returns the button. +- (nonnull id)createButton; + +// Change the alignment of the button +- (void)alignLeft; +- (void)alignCenter; +- (void)alignRight; +- (void)alignFill;//default behavior + +// Show/hide left and right primary buttons. This does not impact the vertical space of the view. +- (void)hidePrimaryLeftButton; +- (void)hidePrimaryRightButton; +- (void)showBothPrimaryButtons; +- (void)hideBothPrimaryButtons; + +- (void)removeSubviews; + + +// update with delegateObject +- (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; + +- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; + +- (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; + +@end diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m new file mode 100644 index 00000000..738810af --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m @@ -0,0 +1,383 @@ +// +// PrimaryButtonView.m +// myverizon +// +// Created by Scott Pfeil on 12/11/15. +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + +#import "PrimaryButtonView.h" +#import +#import +#import +#import "MVMCoreUICommonViewsUtility.h" +#import "MVMCoreUIConstants.h" +#import "UIColor+MFConvenience.h" +#import +@import MVMCore.Swift; + +@interface PrimaryButtonView () + +@property (weak, nonatomic) UIView *twoButtonView; +@property (weak, nonatomic) NSLayoutConstraint *alignCenterPin; +@property (weak, nonatomic) NSLayoutConstraint *alignCenterLeftPin; +@property (weak, nonatomic) NSLayoutConstraint *alignCenterRightPin; +@property (weak, nonatomic) NSLayoutConstraint *height; + +@property (nonatomic, strong) NSArray *horizontalConstraints; + +@end + +@implementation PrimaryButtonView + +- (void)updateView:(CGFloat)size { + [super updateView:size]; + [MVMCoreDispatchUtility performBlockOnMainThread:^{ + [self.primaryButton updateView:size]; + [self.secondaryButton updateView:size]; + }]; +} + +- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; + NSString *backgroundColorString = [json string:@"backgroundColor"]; + if (backgroundColorString) { + self.backgroundColor = [UIColor mfGetColorForHex:backgroundColorString]; + } + NSDictionary *primaryButtonMap = [json dict:@"primaryButton"]; + NSDictionary *secondaryButtonMap = [json dict:@"secondaryButton"]; + [self setupUIWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap]; + [self.primaryButton setAsStandardCustom]; + [self.secondaryButton setAsSecondaryCustom]; + [self.primaryButton setWithJSON:primaryButtonMap delegateObject:delegateObject additionalData:additionalData]; + [self.secondaryButton setWithJSON:secondaryButtonMap delegateObject:delegateObject additionalData:additionalData]; +} + +#pragma mark - Inits + +- (instancetype)init { + if (self = [super init]) { + self.backgroundColor = [UIColor clearColor]; + self.translatesAutoresizingMaskIntoConstraints = NO; + [self setupWithSingleButton]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + self.backgroundColor = [UIColor clearColor]; + self.translatesAutoresizingMaskIntoConstraints = NO; + [self setupWithSingleButton]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor clearColor]; + self.translatesAutoresizingMaskIntoConstraints = NO; + [self setupWithSingleButton]; + } + return self; +} + +- (nonnull instancetype)initButtonSmall:(BOOL)small enabled:(BOOL)enabled { + if (self = [self init]) { + [self.primaryButton setAsSmallButton:small]; + [self.primaryButton setEnabled:enabled]; + } + return self; +} + +- (nonnull instancetype)initWithTwoButtons { + if (self = [self init]) { + [self setupWithTwoButtons]; + } + return self; +} + +#pragma mark - Legacy Setup + +- (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate { + if (self = [self init]) { + [self setupWithButtonMap:buttonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + [self.primaryButton setAsSmallButton:small]; + [self.secondaryButton setAsSmallButton:small]; + } + return self; +} + +- (nonnull instancetype)initWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate { + if (self = [self init]) { + [self setupWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + } + return self; +} + +- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate { + NSDictionary *secondaryButtonMap = [buttonMap dict:KeySecondaryButton]; + NSDictionary *primaryButtonMap = [buttonMap dict:KeyPrimaryButton]; + [self setupWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; +} + +- (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate { + [self setupUIWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap]; + if (primaryButtonMap && secondaryButtonMap) { + [self.primaryButton setWithActionMap:primaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + [self.secondaryButton setWithActionMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + } else if (primaryButtonMap) { + [self.primaryButton setWithActionMap:primaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + self.primaryButton.bordered = NO; + } else { + [self.primaryButton setWithActionMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; + self.primaryButton.bordered = YES; + } +} + +#pragma mark - Setup + +- (void)setupUIWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap { + if (primaryButtonMap && secondaryButtonMap) { + self.height.active = NO; + + // Setup with two buttons + if (!self.primaryButton || !self.secondaryButton) { + [self removeSubviews]; + self.twoButtonView = nil; + [self setupWithTwoButtons]; + } + } else if (primaryButtonMap || secondaryButtonMap) { + self.height.active = NO; + + // Setup with one button. + if (!self.primaryButton || self.secondaryButton) { + [self removeSubviews]; + self.primaryButton = nil; + self.secondaryButton = nil; + [self setupWithSingleButton]; + } + } else { + [self removeSubviews]; + if (!self.height) { + NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]; + height.active = YES; + self.height = height; + } + } +} + +- (id)createButton { + return [PrimaryButton primaryButton:NO]; +} + +- (void)setupWithTwoButtons { + if (self.primaryButton) { + [self.primaryButton removeFromSuperview]; + self.primaryButton = nil; + } + + if (!self.twoButtonView) { + self.backgroundColor = [UIColor clearColor]; + self.translatesAutoresizingMaskIntoConstraints = NO; + + UIView *buttonView = [MVMCoreUICommonViewsUtility commonView]; + + PrimaryButton *leftButton = [PrimaryButton primaryButton]; + leftButton.bordered = YES; + leftButton.translatesAutoresizingMaskIntoConstraints = NO; + [buttonView addSubview:leftButton]; + self.secondaryButton = leftButton; + + PrimaryButton *rightButton = [PrimaryButton primaryButton]; + rightButton.translatesAutoresizingMaskIntoConstraints = NO; + [buttonView addSubview:rightButton]; + self.primaryButton = rightButton; + + [rightButton.widthAnchor constraintEqualToAnchor:leftButton.widthAnchor multiplier:1].active = YES; + + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[leftButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(leftButton)]]; + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[rightButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(rightButton)]]; + self.horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[leftButton]-10-[rightButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(leftButton,rightButton)]; + [NSLayoutConstraint activateConstraints:self.horizontalConstraints]; + [self addSubview:buttonView]; + + [self setupAlignmentsWithView:buttonView]; + + self.twoButtonView = buttonView; + + [self alignCenter]; + } +} + +- (void)setupWithSingleButton { + + if (!self.primaryButton) { + self.backgroundColor = [UIColor clearColor]; + self.translatesAutoresizingMaskIntoConstraints = NO; + + PrimaryButton *button = [self createButton]; + button.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:button]; + self.primaryButton = button; + + [self setupAlignmentsWithView:button]; + + [self alignCenter]; + } +} + +- (void)setupAlignmentsWithView:(UIView *)view { + // Align left and right constants. + NSLayoutConstraint *leftPin = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; + self.leftPin = leftPin; + leftPin.active = YES; + + NSLayoutConstraint *topPin = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; + self.topPin = topPin; + topPin.active = YES; + + NSLayoutConstraint *bottomPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; + self.bottomPin = bottomPin; + bottomPin.active = YES; + + NSLayoutConstraint *rightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + self.rightPin = rightPin; + rightPin.active = YES; + + // Center alignments + NSLayoutConstraint *alignCenter = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]; + self.alignCenterPin = alignCenter; + alignCenter.active = YES; + + NSLayoutConstraint *centerLeftPin = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; + self.alignCenterLeftPin = centerLeftPin; + centerLeftPin.active = YES; + + NSLayoutConstraint *centerRightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + self.alignCenterRightPin = centerRightPin; + centerRightPin.active = YES; +} + +#pragma mark - Configuring + +- (void)alignLeft { + self.alignCenterPin.active = NO; + self.alignCenterLeftPin.active = NO; + self.alignCenterRightPin.active = YES; + self.leftPin.active = YES; + self.rightPin.active = NO; +} + +- (void)alignCenter { + self.alignCenterPin.active = YES; + self.alignCenterLeftPin.active = YES; + self.alignCenterRightPin.active = YES; + self.leftPin.active = NO; + self.rightPin.active = NO; +} + +- (void)alignFill { + self.alignCenterPin.active = NO; + self.alignCenterLeftPin.active = NO; + self.alignCenterRightPin.active = NO; + self.leftPin.active = YES; + self.rightPin.active = YES; +} + +- (void)alignRight { + self.alignCenterPin.active = NO; + self.alignCenterLeftPin.active = YES; + self.alignCenterRightPin.active = NO; + self.leftPin.active = NO; + self.rightPin.active = YES; +} + +- (void)setLeftPinConstant:(CGFloat)constant { + [super setLeftPinConstant:constant]; + self.alignCenterLeftPin.constant = constant; +} + +- (void)setRightPinConstant:(CGFloat)constant { + [super setRightPinConstant:constant]; + self.alignCenterRightPin.constant = constant; +} + +- (void)resetConstraints { + [super resetConstraints]; + self.primaryButton.enabled = NO; +} + +- (void)hidePrimaryLeftButton { + if (!self.secondaryButton.hidden) { + self.secondaryButton.hidden = YES; + PrimaryButton *rightButton = self.primaryButton; + [NSLayoutConstraint deactivateConstraints:self.horizontalConstraints]; + self.horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[rightButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(rightButton)]; + [NSLayoutConstraint activateConstraints:self.horizontalConstraints]; + } +} + +- (void)hidePrimaryRightButton { + if (!self.primaryButton.hidden) { + self.primaryButton.hidden = YES; + PrimaryButton *leftButton = self.secondaryButton; + [NSLayoutConstraint deactivateConstraints:self.horizontalConstraints]; + self.horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[leftButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(leftButton)]; + [NSLayoutConstraint activateConstraints:self.horizontalConstraints]; + } +} + +- (void)showBothPrimaryButtons { + self.primaryButton.hidden = NO; + self.secondaryButton.hidden = NO; + PrimaryButton *rightButton = self.primaryButton; + PrimaryButton *leftButton = self.secondaryButton; + [NSLayoutConstraint deactivateConstraints:self.horizontalConstraints]; + self.horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[leftButton]-10-[rightButton]-0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(leftButton,rightButton)]; + [NSLayoutConstraint activateConstraints:self.horizontalConstraints]; +} + +- (void)hideBothPrimaryButtons { + self.primaryButton.hidden = YES; + self.secondaryButton.hidden = YES; +} + +- (void)removeSubviews { + for (UIView *view in self.subviews) { + [view removeFromSuperview]; + } +} + + + +// update with delegateObject +- (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { + NSObject *buttonDelegate; + NSObject *actionDelegate = delegateObject.actionDelegate; + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; + } + return [self initButtonSmall:small buttonMap:buttonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; +} + +- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegate:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { + NSObject *buttonDelegate; + NSObject *actionDelegate = delegateObject.actionDelegate; + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; + } + [self setupWithButtonMap:buttonMap actionDelegate:actionDelegate additionalData:nil buttonDelegate:buttonDelegate]; +} + + +- (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { + NSObject *buttonDelegate; + NSObject *actionDelegate = delegateObject.actionDelegate; + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; + } + [self setupWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; +} + +@end From 9ce1e7ec93616dcec7a714b2c61a07f56c7df134 Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Wed, 29 Jan 2020 11:27:24 -0500 Subject: [PATCH 06/29] add PrimaryButtonView back to prepay legacy view/ view controller --- .../HorizontalCombinationViews/PrimaryButtonView.h | 2 ++ .../HorizontalCombinationViews/PrimaryButtonView.m | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h index c0e8994d..9c290fcf 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h @@ -54,6 +54,8 @@ // update with delegateObject - (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; +- (nonnull instancetype)initWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; + - (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; - (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m index 738810af..07fd0ff4 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m @@ -361,6 +361,15 @@ return [self initButtonSmall:small buttonMap:buttonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; } +- (nonnull instancetype)initWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { + NSObject *buttonDelegate; + NSObject *actionDelegate = delegateObject.actionDelegate; + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; + } + return [self initWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; +} + - (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegate:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { NSObject *buttonDelegate; NSObject *actionDelegate = delegateObject.actionDelegate; From 54dc30a41a6335749f0741f21ff9b9003ab0dc5e Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Wed, 29 Jan 2020 15:47:37 -0500 Subject: [PATCH 07/29] update based on Scott's comments --- .../HorizontalCombinationViews/PrimaryButtonView.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m index 07fd0ff4..1bcc6a9e 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m @@ -353,7 +353,7 @@ // update with delegateObject - (nonnull instancetype)initButtonSmall:(BOOL)small buttonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { - NSObject *buttonDelegate; + NSObject *buttonDelegate = nil; NSObject *actionDelegate = delegateObject.actionDelegate; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; @@ -362,7 +362,7 @@ } - (nonnull instancetype)initWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { - NSObject *buttonDelegate; + NSObject *buttonDelegate = nil; NSObject *actionDelegate = delegateObject.actionDelegate; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; @@ -371,7 +371,7 @@ } - (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegate:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { - NSObject *buttonDelegate; + NSObject *buttonDelegate = nil; NSObject *actionDelegate = delegateObject.actionDelegate; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; @@ -381,7 +381,7 @@ - (void)setupWithPrimaryButtonMap:(nullable NSDictionary *)primaryButtonMap secondaryButtonMap:(nullable NSDictionary *)secondaryButtonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { - NSObject *buttonDelegate; + NSObject *buttonDelegate = nil; NSObject *actionDelegate = delegateObject.actionDelegate; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; From f367b03233f4acb2d7f458351a093bfaf8248044 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 30 Jan 2020 11:41:43 -0500 Subject: [PATCH 08/29] Review comments --- MVMCoreUI/Atoms/Buttons/PillButton.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index fc752f7a..262a780d 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -64,11 +64,11 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation } private func getInnerPadding() -> CGFloat { - return (getHeight() / 2.0) + return getHeight() / 2.0 } private func getHeight() -> CGFloat { - PillButton.getHeight(for: (model as? ButtonModel)?.size, size: size) + PillButton.getHeight(for: buttonModel?.size, size: size) } public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { @@ -81,7 +81,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation } private func getMinimumWidth() -> CGFloat { - switch buttonModel?.size ?? .standard { + switch buttonModel?.size { case .tiny: return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0 default: @@ -96,7 +96,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation } // MARK: - ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { // The button will get styled in the enable check in super. super.setWithModel(model, delegateObject, additionalData) @@ -104,7 +104,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation setTitle(model.title, for: .normal) if let required = model.required, - required == true { + required { FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) } } From 58a40a775237a184c7d5ccf1eebb76948e729d51 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 30 Jan 2020 11:56:37 -0500 Subject: [PATCH 09/29] fixes and color addition --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 25 +++++++++++++++++++++++ MVMCoreUI/Atoms/Buttons/PillButton.swift | 25 ++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index ce513a03..9eb284d7 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -27,6 +27,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public var enabled: Bool = true public var style: ButtonStyle? public var size: ButtonSize? = .standard + public var fillColor: Color? + public var textColor: Color? + public var borderColor: Color? + public var disabledFillColor: Color? + public var disabledTextColor: Color? + public var disabledBorderColor: Color? public var required: Bool? public var requiredGroups: [String]? @@ -43,6 +49,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { case enabled case style case size + case fillColor + case textColor + case borderColor + case disabledFillColor + case disabledTextColor + case disabledBorderColor case required case requiredGroups } @@ -65,6 +77,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { self.enabled = enabled } + fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor) + textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) + borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) + disabledFillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledFillColor) + disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) + disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) } public func encode(to encoder: Encoder) throws { @@ -76,6 +94,13 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(enabled, forKey: .enabled) try container.encodeIfPresent(style, forKey: .style) try container.encodeIfPresent(size, forKey: .size) + try container.encodeIfPresent(fillColor, forKey: .fillColor) + try container.encodeIfPresent(textColor, forKey: .textColor) + try container.encodeIfPresent(borderColor, forKey: .borderColor) + try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor) + try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor) + try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor) try container.encodeIfPresent(required, forKey: .required) + try container.encodeIfPresent(requiredGroups, forKey: .requiredGroups) } } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 262a780d..403e9bc8 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -45,7 +45,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation setTitleColor(.black, for: .normal) setTitleColor(.mvmCoolGray6, for: .disabled) backgroundColor = .clear - layer.borderWidth = 1; + layer.borderWidth = 1 if isEnabled { layer.borderColor = UIColor.black.cgColor } else { @@ -61,6 +61,29 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation default: stylePrimary() } + if let titleColor = buttonModel?.textColor { + setTitleColor(titleColor.uiColor, for: .normal) + } + if let disabledTitleColor = buttonModel?.disabledTextColor { + setTitleColor(disabledTitleColor.uiColor, for: .disabled) + } + if isEnabled { + if let fillColor = buttonModel?.fillColor { + backgroundColor = fillColor.uiColor + } + if let borderColor = buttonModel?.borderColor { + layer.borderWidth = 1 + layer.borderColor = borderColor.cgColor + } + } else { + if let fillColor = buttonModel?.disabledFillColor { + backgroundColor = fillColor.uiColor + } + if let borderColor = buttonModel?.disabledBorderColor { + layer.borderWidth = 1 + layer.borderColor = borderColor.cgColor + } + } } private func getInnerPadding() -> CGFloat { From 521fc75e59199fcc532aa9487a99f76ae8b4ba2d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 30 Jan 2020 11:56:57 -0500 Subject: [PATCH 10/29] remove unused --- MVMCoreUI/Atoms/Buttons/PillButton.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 403e9bc8..0d0a3090 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -32,7 +32,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation public func stylePrimary() { setTitleColor(.white, for: .normal) setTitleColor(.white, for: .disabled) - layer.borderWidth = 0; + layer.borderWidth = 0 if isEnabled { backgroundColor = .black } else { From 487d41b3d99a28649f5b17fa0d9cfbd68f917afb Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:01:06 -0500 Subject: [PATCH 11/29] two button view update --- .../TwoButtonView.swift | 333 ++++-------------- 1 file changed, 62 insertions(+), 271 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 5c80bd1a..9a4f31f9 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -8,11 +8,10 @@ import UIKit -@objcMembers open class TwoButtonView: ViewConstrainingView { - open var primaryButton: PrimaryButton? = PrimaryButton.button() - open var secondaryButton: PrimaryButton? = PrimaryButton.button() - open var viewForButtons: UIView? - public var heightConstraint: NSLayoutConstraint? +@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol { + open var primaryButton: PillButton = PillButton() + open var secondaryButton: PillButton = PillButton() + private var stack = UIStackView() public init() { super.init(frame: .zero) @@ -26,289 +25,81 @@ import UIKit super.init(frame: frame) } - public func setDefaultCustom() { - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() + public func setDefault() { + primaryButton.stylePrimary() + secondaryButton.styleSecondary() } // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.primaryButton?.updateView(size) - self.secondaryButton?.updateView(size) - }) + self.primaryButton.updateView(size) + self.secondaryButton.updateView(size) } open override func setupView() { super.setupView() - setupWithTwoButtons() - secondaryButton?.bordered = true + + stack.translatesAutoresizingMaskIntoConstraints = false + addSubview(stack) + stack.addArrangedSubview(primaryButton) + stack.addArrangedSubview(secondaryButton) + NSLayoutConstraint.constraintPinSubview(toSuperview: stack) + stack.axis = .horizontal + stack.spacing = 10 + } + + // MARK: - Stack Manipulation + public func showPrimaryButton() { + if primaryButton.superview == nil { + stack.addArrangedSubview(primaryButton) + } + } + + public func showSecondaryButton() { + if secondaryButton.superview == nil { + stack.addArrangedSubview(secondaryButton) + } + } + + public func hidePrimaryButton() { + if primaryButton.superview != nil { + stack.removeArrangedSubview(primaryButton) + } + } + + public func hideSecondaryButton() { + if secondaryButton.superview != nil { + stack.removeArrangedSubview(secondaryButton) + } } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton") - let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton") - set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - open override func reset() { super.reset() - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() + setDefault() } - - // MARK: - Constraining - func createPrimaryButton() { - if primaryButton == nil { - primaryButton = PrimaryButton.button() - } - } - - func createSecondaryButton() { - if secondaryButton == nil { - secondaryButton = PrimaryButton.button() - secondaryButton?.bordered = true - } - } - - func removeButtons() { - viewForButtons?.removeFromSuperview() - primaryButton?.removeFromSuperview() - secondaryButton?.removeFromSuperview() - viewForButtons = nil - secondaryButton = nil - primaryButton = nil - } - - open func setupConstraintsForViewWithButtons() { - guard let viewForButtons = viewForButtons, - let primaryButton = primaryButton, - let secondaryButton = secondaryButton - else { return } - - viewForButtons.addSubview(primaryButton) - viewForButtons.addSubview(secondaryButton) - secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1).isActive = true - NSLayoutConstraint.constraintPinSubview(secondaryButton, pinTop: true, pinBottom: true, pinLeft: true, pinRight: false) - NSLayoutConstraint.constraintPinSubview(primaryButton, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) - let constraint = primaryButton.leadingAnchor.constraint(equalTo: secondaryButton.trailingAnchor, constant: 10) - constraint.priority = UILayoutPriority(900) - constraint.isActive = true - } - - func setupWithTwoButtons() { - guard viewForButtons == nil else { - return - } - let viewForButtons = MVMCoreUICommonViewsUtility.commonView() - addSubview(viewForButtons) - self.viewForButtons = viewForButtons - - pinView(toSuperView: viewForButtons) - alignCenterHorizontal() - createPrimaryButton() - createSecondaryButton() - setupConstraintsForViewWithButtons() - } - - open func setupWithPrimaryButton() { - guard primaryButton == nil && secondaryButton == nil else { - return - } - createPrimaryButton() - if let primaryButton = primaryButton { - addSubview(primaryButton) - pinView(toSuperView: primaryButton) - alignCenterHorizontal() - } - } - - open func setupWithSecondaryButton() { - guard secondaryButton == nil && primaryButton == nil else { - return - } - createSecondaryButton() - if let secondaryButton = secondaryButton { - addSubview(secondaryButton) - pinView(toSuperView: secondaryButton) - alignCenterHorizontal() - } - } - - /// Legacy - func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) { - setupUI(primaryButtonShowing: primaryButtonMap != nil, secondaryButtonShowing: secondaryButtonMap != nil) - } - - func setupUI(primaryButtonShowing: Bool, secondaryButtonShowing: Bool) { - if primaryButtonShowing, secondaryButtonShowing { - heightConstraint?.isActive = false - if primaryButton == nil || secondaryButton == nil { - removeButtons() - setupWithTwoButtons() - } - } else if primaryButtonShowing { - heightConstraint?.isActive = false - if primaryButton == nil || secondaryButton != nil { - removeButtons() - setupWithPrimaryButton() - } - } else if secondaryButtonShowing { - heightConstraint?.isActive = false - if secondaryButton == nil || primaryButton != nil { - removeButtons() - setupWithSecondaryButton() - } - } else { - removeButtons() - if heightConstraint == nil { - heightConstraint = heightAnchor.constraint(equalToConstant: 0) - heightConstraint?.isActive = true - } - } - } - - open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON) - setDefaultCustom() - primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) - } - - // MARK: - Legacy - public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - self.init() - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } - - public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: AnyHashable]?) { - self.init() - setup(withButtonMap: buttonMap, delegateObject: delegateObject, additionalData: additionalData) - primaryButton?.setAsSmall(small) - secondaryButton?.setAsSmall(small) - } - - public convenience init(buttonSmall small: Bool, enabled: Bool) { - self.init() - removeButtons() - setupWithPrimaryButton() - primaryButton?.setAsSmall(small) - primaryButton?.isEnabled = enabled - } - - open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) - if primaryButtonMap != nil, secondaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } else if primaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - primaryButton?.bordered = false - } else if secondaryButtonMap != nil { - secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.bordered = true - } - } - - open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) - let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } - - public func hideLeftButton() { - guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else { - return - } - secondaryButton.isHidden = true - if let primaryButton = primaryButton { - primaryButton.removeFromSuperview() - viewForButtons?.addSubview(primaryButton) - NSLayoutConstraint.constraintPinSubview(toSuperview: primaryButton) - } - } - - public func hideRightButton() { - guard let primaryButton = primaryButton, !primaryButton.isHidden else { - return - } - primaryButton.isHidden = true - if let secondaryButton = secondaryButton { - secondaryButton.removeFromSuperview() - viewForButtons?.addSubview(secondaryButton) - NSLayoutConstraint.constraintPinSubview(toSuperview: secondaryButton) - } - } - - public func showBothButtons() { - primaryButton?.isHidden = false - secondaryButton?.isHidden = false - if let primaryButton = primaryButton, let secondaryButton = secondaryButton { - primaryButton.removeFromSuperview() - secondaryButton.removeFromSuperview() - setupConstraintsForViewWithButtons() - } - } - - public func hideBothButtons() { - primaryButton?.isHidden = true - secondaryButton?.isHidden = true - } - - override open func horizontalAlignment() -> UIStackView.Alignment { + + // MARK: - MVMCoreUIViewConstrainingProtocol + open func horizontalAlignment() -> UIStackView.Alignment { return .center } -} - -// MARK: - Deprecate -extension TwoButtonView { - @available(*, deprecated) - open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) - if primaryButtonMap != nil, secondaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - } else if primaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - primaryButton?.bordered = false - } else if secondaryButtonMap != nil { - secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - secondaryButton?.bordered = true + + // MARK: - ModelMoleculeViewProtocol + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + guard let model = model as? TwoButtonViewModel else { return } + if let primaryModel = model.primaryButton { + showPrimaryButton() + primaryButton.setWithModel(primaryModel, delegateObject, additionalData) + } else { + hidePrimaryButton() + } + if let secondaryModel = model.secondaryButton { + showSecondaryButton() + secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData) + } else { + hideSecondaryButton() } } - - @available(*, deprecated) - open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) - let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } - - @available(*, deprecated) - public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { - self.init() - setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - primaryButton?.setAsSmall(small) - secondaryButton?.setAsSmall(small) - } - - @available(*, deprecated) - public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - self.init() - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } -} - -extension TwoButtonView: ModelMoleculeViewProtocol { - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let model = model as? TwoButtonViewModel else { return } - setupUI(primaryButtonShowing: model.primaryButton != nil, secondaryButtonShowing: model.secondaryButton != nil) - setDefaultCustom() - primaryButton?.setWithModel(model.primaryButton, delegateObject, additionalData) - secondaryButton?.setWithModel(model.secondaryButton, delegateObject, additionalData) - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } } From 37228669e08678469549523d5bf2647a4f7f3ff7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:27:20 -0500 Subject: [PATCH 12/29] Two button remove legacy --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 6 ++++ .../TwoButtonView.swift | 17 ++++++++++- .../TwoButtonViewModel.swift | 28 ++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 9eb284d7..cfe8bb2f 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -41,6 +41,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { self.action = action } + init(secondaryButtonWith title: String, action: ActionModelProtocol) { + self.title = title + self.action = action + style = .secondary + } + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 9a4f31f9..a12bf03f 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -12,7 +12,8 @@ import UIKit open var primaryButton: PillButton = PillButton() open var secondaryButton: PillButton = PillButton() private var stack = UIStackView() - + private var equalWidthConstraint: NSLayoutConstraint? + public init() { super.init(frame: .zero) } @@ -47,31 +48,45 @@ import UIKit NSLayoutConstraint.constraintPinSubview(toSuperview: stack) stack.axis = .horizontal stack.spacing = 10 + equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1) + equalWidthConstraint?.isActive = true } // MARK: - Stack Manipulation public func showPrimaryButton() { if primaryButton.superview == nil { stack.addArrangedSubview(primaryButton) + primaryButton.isHidden = false + } + if secondaryButton.superview != nil { + equalWidthConstraint?.isActive = true } } public func showSecondaryButton() { if secondaryButton.superview == nil { stack.addArrangedSubview(secondaryButton) + secondaryButton.isHidden = false + } + if primaryButton.superview != nil { + equalWidthConstraint?.isActive = true } } public func hidePrimaryButton() { if primaryButton.superview != nil { stack.removeArrangedSubview(primaryButton) + primaryButton.isHidden = true } + equalWidthConstraint?.isActive = false } public func hideSecondaryButton() { if secondaryButton.superview != nil { stack.removeArrangedSubview(secondaryButton) + secondaryButton.isHidden = true } + equalWidthConstraint?.isActive = false } // MARK: - MVMCoreUIMoleculeViewProtocol diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index a7abde9f..5938692b 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -8,9 +8,35 @@ import UIKit -public struct TwoButtonViewModel: MoleculeModelProtocol { +public class TwoButtonViewModel: MoleculeModelProtocol { public static var identifier: String = "twoButtonView" public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case primaryButton + case secondaryButton + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton) + secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton) + // Default value + if secondaryButton?.style == nil { + secondaryButton?.style = .secondary + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(primaryButton, forKey: .primaryButton) + try container.encodeIfPresent(secondaryButton, forKey: .secondaryButton) + } } From e2f1da7c276519ade5e87568f3da296c5a38dd36 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:29:46 -0500 Subject: [PATCH 13/29] estimated height --- .../Molecules/HorizontalCombinationViews/TwoButtonView.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index a12bf03f..31fd6f37 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -101,6 +101,11 @@ import UIKit } // MARK: - ModelMoleculeViewProtocol + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = molecule as? TwoButtonViewModel else { return 0 } + return PillButton.estimatedHeight(forRow: model.primaryButton ?? model.secondaryButton, delegateObject: delegateObject) + } + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) guard let model = model as? TwoButtonViewModel else { return } From 205e9707e6a92ec9c04bf2094d59cc73fee795f3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:37:24 -0500 Subject: [PATCH 14/29] move legacy --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++-- .../Views}/PrimaryButtonView.h | 0 .../Views}/PrimaryButtonView.m | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename MVMCoreUI/{Molecules/HorizontalCombinationViews => Legacy/Views}/PrimaryButtonView.h (100%) rename MVMCoreUI/{Molecules/HorizontalCombinationViews => Legacy/Views}/PrimaryButtonView.m (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a35514cb..1a84907a 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -827,6 +827,8 @@ D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, + 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, + 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, D282AACA2243C61700C46919 /* ButtonView.swift */, ); path = Views; @@ -871,8 +873,6 @@ D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */, D28A837E23CCA96400DFE4FC /* TabsModel.swift */, - 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, - 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, ); path = HorizontalCombinationViews; sourceTree = ""; diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h b/MVMCoreUI/Legacy/Views/PrimaryButtonView.h similarity index 100% rename from MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h rename to MVMCoreUI/Legacy/Views/PrimaryButtonView.h diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Legacy/Views/PrimaryButtonView.m similarity index 100% rename from MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m rename to MVMCoreUI/Legacy/Views/PrimaryButtonView.m From c81f68d66dacbdedffc5ba5e3af6beaa73dda0d0 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 3 Feb 2020 08:54:41 -0500 Subject: [PATCH 15/29] adding color and removing pointless loop. --- MVMCoreUI/Categories/UIColor+Extension.swift | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index fab1ae6f..aec1ce17 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -25,6 +25,7 @@ extension UIColor { "coolGray1": (.mvmCoolGray1, "#F6F6F6"), "coolGray3": (.mvmCoolGray3, "#D8DADA"), "coolGray6": (.mvmCoolGray6, "#747676"), + "coolGray10": (.mvmCoolGray10, "#333333"), "vzupGold": (.vzupGold, "#B89B56"), "vzupYellow1": (.vzupYellow1, "#F9D542"), "vzupYellow2": (.vzupYellow2, "#F4CA53"), @@ -67,6 +68,9 @@ extension UIColor { /// HEX: #747676 public static let mvmCoolGray6 = UIColor.color8Bits(red: 116, green: 118, blue: 118) + /// HEX: #333333 + public static let mvmCoolGray10 = UIColor.grayscale(rgb: 51) + //-------------------------------------------------- // MARK: - VZ UP Brand //-------------------------------------------------- @@ -199,12 +203,6 @@ extension UIColor { public class func getColorAndHexFromName(_ name: String) -> ColorHexTuple? { - for row in names { - if name == row.key { - return row.value - } - } - - return nil + return names[name] } } From be2e9473b3f2b6a7a53cb1539e68135a48267213 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 3 Feb 2020 09:00:03 -0500 Subject: [PATCH 16/29] Removing func as the static dictionary can carry the weight. --- MVMCoreUI/Categories/UIColor+Extension.swift | 7 +------ MVMCoreUI/CustomPrimitives/Color.swift | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index aec1ce17..55a10c03 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -6,11 +6,11 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // - import UIKit public typealias ColorHexTuple = (uiColor: UIColor, hex: String) + extension UIColor { /// Dictionary to access brand approved colors by name. @@ -200,9 +200,4 @@ extension UIColor { return nil } - - public class func getColorAndHexFromName(_ name: String) -> ColorHexTuple? { - - return names[name] - } } diff --git a/MVMCoreUI/CustomPrimitives/Color.swift b/MVMCoreUI/CustomPrimitives/Color.swift index d72e1af9..a34fbd45 100644 --- a/MVMCoreUI/CustomPrimitives/Color.swift +++ b/MVMCoreUI/CustomPrimitives/Color.swift @@ -56,7 +56,7 @@ public final class Color: Codable { } init?(name: String) { - guard let colorTuple = UIColor.getColorAndHexFromName(name) else { return nil } + guard let colorTuple = UIColor.names[name] else { return nil } self.uiColor = colorTuple.uiColor self.hex = colorTuple.hex determineRGBA() @@ -73,7 +73,7 @@ public final class Color: Codable { if colorString.hasPrefix("#") { hex = colorString.replacingOccurrences(of: "#", with: "") } else { - guard let hex = UIColor.getColorAndHexFromName(colorString)?.hex else { throw ColorError.badName(reason: "Check the spelling of your color.") } + guard let hex = UIColor.names[colorString]?.hex else { throw ColorError.badName(reason: "Check the spelling of your color.") } self.hex = hex.replacingOccurrences(of: "#", with: "") name = colorString } From 9110c842a54db82edd949ad5675b82e73b6d8c52 Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Mon, 3 Feb 2020 09:42:11 -0500 Subject: [PATCH 17/29] fix typo --- .../Molecules/HorizontalCombinationViews/PrimaryButtonView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m index 1bcc6a9e..8c76353c 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m @@ -370,7 +370,7 @@ return [self initWithPrimaryButtonMap:primaryButtonMap secondaryButtonMap:secondaryButtonMap actionDelegate:actionDelegate additionalData:additionalData buttonDelegate:buttonDelegate]; } -- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegate:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { +- (void)setupWithButtonMap:(nullable NSDictionary *)buttonMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { NSObject *buttonDelegate = nil; NSObject *actionDelegate = delegateObject.actionDelegate; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { From c83302ec089b1a835ccbd67eceea3cb77c8d4f3a Mon Sep 17 00:00:00 2001 From: "Chintakrinda, Arun Kumar (Arun)" Date: Tue, 4 Feb 2020 14:37:31 +0530 Subject: [PATCH 18/29] Stack model bug fix from molecueStack to stack --- MVMCoreUI/Templates/StackPageTemplateModel.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Templates/StackPageTemplateModel.swift b/MVMCoreUI/Templates/StackPageTemplateModel.swift index b9a54125..10a2cf6f 100644 --- a/MVMCoreUI/Templates/StackPageTemplateModel.swift +++ b/MVMCoreUI/Templates/StackPageTemplateModel.swift @@ -30,14 +30,14 @@ import Foundation case screenHeading case header case footer - case moleculeStack + case stack case isAtomicTabs } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) pageType = try typeContainer.decode(String.self, forKey: .pageType) - moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .moleculeStack) + moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .stack) screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) @@ -47,7 +47,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(pageType, forKey: .pageType) - try container.encode(moleculeStack, forKey: .moleculeStack) + try container.encode(moleculeStack, forKey: .stack) try container.encodeIfPresent(screenHeading, forKey: .screenHeading) try container.encodeIfPresent(isAtomicTabs, forKey: .isAtomicTabs) try container.encodeModelIfPresent(header, forKey: .header) From fe15372437be007b758fd9abf0842a7bb78a8b28 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 4 Feb 2020 12:08:26 -0500 Subject: [PATCH 19/29] defect fixes --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 14 ++++++++++++-- MVMCoreUI/Atoms/Views/MultiProgress.swift | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 3fcf453a..83f27854 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -49,7 +49,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI didSet { changeCaretColor() } } - public func updateView(_ size: CGFloat) { } + public func updateView(_ size: CGFloat) { + titleLabel?.font = MFStyler.fontB1() + } //------------------------------------------------------ // MARK: - Methods @@ -61,10 +63,18 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI setTitleColor(disabledColor, for: .disabled) if let rightCaretView = rightView as? CaretView { + rightCaretView.enabledColor = enabledColor + rightCaretView.disabledColor = disabledColor rightCaretView.isEnabled = isEnabled } } + private func createCaretView() -> CaretView { + let caret = CaretView() + caret.lineWidth = 1.5 + return caret + } + private func addCaretImageView() { rightView?.removeFromSuperview() @@ -75,7 +85,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI let edgeInsets: UIEdgeInsets = contentEdgeInsets contentEdgeInsets = UIEdgeInsets(top: edgeInsets.top, left: edgeInsets.left, bottom: edgeInsets.bottom, right: 4 + width) - let caretView: UIView = rightView ?? CaretView() + let caretView: UIView = rightView ?? createCaretView() rightView = caretView rightView?.translatesAutoresizingMaskIntoConstraints = false addSubview(caretView) diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index cee425cc..cd05ed0b 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgress.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgress.swift @@ -31,7 +31,7 @@ import UIKit view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) view.backgroundColor = progressObject.progressColor.uiColor - view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress).isActive = true + view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress/100.0).isActive = true view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true previous = view NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false) From 40da48bc6e891cead3811b63645a2f9bb3a1e4cf Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 4 Feb 2020 13:34:39 -0500 Subject: [PATCH 20/29] Fix stack percent defect --- MVMCoreUI/Organisms/Stack.swift | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 2ab77421..4e7a3114 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -33,8 +33,9 @@ open class Stack: Container where T: StackModelProtocol { }) // Adds the views + let totalSpace = getTotalSpace() for (index, view) in stackItems.enumerated() { - addView(view, stackModel.molecules[index], percentModifier: getPercentModifier(), lastItem: lastItemIndex == index) + addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index) } } @@ -173,14 +174,12 @@ open class Stack: Container where T: StackModelProtocol { // MARK: - Adding to stack /// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved. - private func getPercentModifier() -> CGFloat { + private func getTotalSpace() -> CGFloat { guard let stackModel = stackModel else { return 0.0 } var totalSpace: CGFloat = 0.0 - var totalViews = 0 var firstMoleculeFound = false for stackItemModel in stackModel.molecules { guard !stackItemModel.gone else { continue } - totalViews += 1 let spacing = stackItemModel.spacing ?? stackModel.spacing if firstMoleculeFound { totalSpace += spacing @@ -189,11 +188,11 @@ open class Stack: Container where T: StackModelProtocol { totalSpace += (stackModel.useStackSpacingBeforeFirstItem ? spacing : stackItemModel.spacing ?? 0) } } - return (totalViews > 0 ? -(totalSpace / CGFloat(totalViews)) : 0) + return totalSpace } /// Adds the stack item view - private func addView(_ view: UIView,_ model: StackItemModelProtocol, percentModifier: CGFloat, lastItem: Bool) { + private func addView(_ view: UIView,_ model: StackItemModelProtocol, totalSpacing: CGFloat, lastItem: Bool) { guard let stackModel = self.stackModel else { return } guard !model.gone else { // Gone views do not show @@ -223,7 +222,9 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true + let multiplier = CGFloat(percent)/100.0 + let constant = multiplier * totalSpacing + view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) @@ -240,7 +241,9 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true + let multiplier = CGFloat(percent)/100.0 + let constant = multiplier * totalSpacing + view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0) From 2b74531ce105514eb200902c64b22bb40566c713 Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Tue, 4 Feb 2020 13:59:14 -0500 Subject: [PATCH 21/29] change CaretButton to MFCaretButton in legacy view/viewcontroller, CaretButton will be only used in molecule --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++ MVMCoreUI/Legacy/Views/MFCaretButton.h | 26 ++++++ MVMCoreUI/Legacy/Views/MFCaretButton.m | 113 +++++++++++++++++++++++++ MVMCoreUI/Legacy/Views/MFCaretView.h | 16 ++++ MVMCoreUI/Legacy/Views/MFCaretView.m | 93 ++++++++++++++++++++ MVMCoreUI/MVMCoreUI.h | 2 + 6 files changed, 266 insertions(+) create mode 100644 MVMCoreUI/Legacy/Views/MFCaretButton.h create mode 100644 MVMCoreUI/Legacy/Views/MFCaretButton.m create mode 100644 MVMCoreUI/Legacy/Views/MFCaretView.h create mode 100644 MVMCoreUI/Legacy/Views/MFCaretView.m diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a35514cb..1e0743b4 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -106,6 +106,10 @@ 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + 94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A3C23E9D13900676048 /* MFCaretButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A3D23E9D13900676048 /* MFCaretButton.m */; }; + 94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A4023E9D19E00676048 /* MFCaretView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A4123E9D19E00676048 /* MFCaretView.m */; }; 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */; }; 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */; }; 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */; }; @@ -420,6 +424,10 @@ 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + 94AF4A3C23E9D13900676048 /* MFCaretButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretButton.h; sourceTree = ""; }; + 94AF4A3D23E9D13900676048 /* MFCaretButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretButton.m; sourceTree = ""; }; + 94AF4A4023E9D19E00676048 /* MFCaretView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretView.h; sourceTree = ""; }; + 94AF4A4123E9D19E00676048 /* MFCaretView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretView.m; sourceTree = ""; }; 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = ""; }; 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderlineModel.swift; sourceTree = ""; }; 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThroughModel.swift; sourceTree = ""; }; @@ -828,6 +836,10 @@ D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, D282AACA2243C61700C46919 /* ButtonView.swift */, + 94AF4A3C23E9D13900676048 /* MFCaretButton.h */, + 94AF4A3D23E9D13900676048 /* MFCaretButton.m */, + 94AF4A4023E9D19E00676048 /* MFCaretView.h */, + 94AF4A4123E9D19E00676048 /* MFCaretView.m */, ); path = Views; sourceTree = ""; @@ -1408,6 +1420,7 @@ D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */, D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */, D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */, + 94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */, 0A21DB8A235E06EF00C160A2 /* MFDigitTextBox.h in Headers */, D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */, 0A21DB8C235E06EF00C160A2 /* MFDigitTextField.h in Headers */, @@ -1426,6 +1439,7 @@ D29DF2CA21E7BFC8003B2FB9 /* MFSizeThreshold.h in Headers */, D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */, D29DF2BD21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.h in Headers */, + 94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */, D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */, D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */, D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */, @@ -1671,6 +1685,7 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, + 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, @@ -1720,6 +1735,7 @@ D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, + 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, diff --git a/MVMCoreUI/Legacy/Views/MFCaretButton.h b/MVMCoreUI/Legacy/Views/MFCaretButton.h new file mode 100644 index 00000000..c6426e35 --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretButton.h @@ -0,0 +1,26 @@ +// +// MFCaretButton.h +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import +#import + +@interface MFCaretButton : MFCustomButton + +@property (nullable, nonatomic, strong) UIView *rightView; +@property (nullable, nonatomic, strong) NSNumber *rightViewHeight; +@property (nullable, nonatomic, strong) NSNumber *rightViewWidth; + +-(void)updateCaretSpacing:(CGFloat)spacing; + +/* The fill color of the Caret and titleLabel. The default is blackColor */ +-(void)setEnableCaretColor:(nullable UIColor *)enableCaretColor; + +/* The fill color of the Caret and titleLabel. The default is mfSilver */ +-(void)setDisabledCaretColor:(nullable UIColor *)disabledCaretColor; + +@end diff --git a/MVMCoreUI/Legacy/Views/MFCaretButton.m b/MVMCoreUI/Legacy/Views/MFCaretButton.m new file mode 100644 index 00000000..bd8f058c --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretButton.m @@ -0,0 +1,113 @@ +// +// MFCaretButton.m +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import "MFCaretButton.h" +#import "MFCaretView.h" +#import "UIColor+MFConvenience.h" + +@interface MFCaretButton () + +@property (nonatomic, strong) UIColor *enableColor; +@property (nonatomic, strong) UIColor *disabledColor; +@property (nonatomic, strong) NSLayoutConstraint *caretSpacingConstraint; + +@end + +@implementation MFCaretButton + +CGFloat const CaretViewHeight = 10.8f; +CGFloat const CaretViewWidth = 6.6f; + + +- (void)layoutSubviews { + [self addCaretImageView]; + [super layoutSubviews]; +} + +- (void)setEnabled:(BOOL)enabled { + [super setEnabled:enabled]; + [self changeCaretColor]; +} +- (void)changeCaretColor { + [self setTitleColor:self.enableColor forState:UIControlStateNormal]; + [self setTitleColor:self.disabledColor forState:UIControlStateDisabled]; + if ([self.rightView isKindOfClass:[MFCaretView class]]) { + MFCaretView *caretView = (MFCaretView *)self.rightView; + if (self.enabled) { + [caretView setLineColor:self.enableColor]; + } else { + [caretView setLineColor:self.disabledColor]; + } + } +} + +- (void)addCaretImageView { + [self.rightView removeFromSuperview]; + UIEdgeInsets edgeInsets = self.contentEdgeInsets; + CGFloat rightInset = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth; + UIEdgeInsets newInsets = UIEdgeInsetsMake(edgeInsets.top, edgeInsets.left, edgeInsets.bottom, 4 + rightInset); + self.contentEdgeInsets = newInsets; + UIView *caretViewIs = self.rightView; + if (!self.rightView) { + caretViewIs = [[MFCaretView alloc]init]; + self.rightView = caretViewIs; + } + self.rightView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:self.rightView]; + + CGFloat width = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth; + NSLayoutConstraint *caretViewWidthConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width]; + caretViewWidthConstraint.active = YES; + + CGFloat height = self.rightViewHeight?self.rightViewHeight.floatValue:CaretViewHeight; + NSLayoutConstraint *caretViewHeightConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height]; + caretViewHeightConstraint.active = YES; + + NSLayoutConstraint *caretLabelSpacing = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeRight multiplier:1.0 constant:4.0]; + caretLabelSpacing.active = YES; + self.caretSpacingConstraint = caretLabelSpacing; + + NSLayoutConstraint *caretCenterY = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]; + caretCenterY.active = YES; + + NSLayoutConstraint *caretLabelRightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:caretViewIs attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + caretLabelRightPin.active = YES; + self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + //set correct color after layout + [self changeCaretColor]; +} +- (void)updateCaretSpacing:(CGFloat)spacing { + if (self.caretSpacingConstraint != nil) { + self.caretSpacingConstraint.constant = spacing; + } +} +- (void)setEnableCaretColor:(UIColor *)enableCaretColor { + self.enableColor = enableCaretColor; + [self changeCaretColor]; +} +- (void)setDisabledCaretColor:(UIColor *)disabledCaretColor { + self.disabledColor = disabledCaretColor; + [self changeCaretColor]; +} +@synthesize enableColor = _enableColor; +- (UIColor *)enableColor { + if (!_enableColor) { + _enableColor = [UIColor blackColor]; + } + return _enableColor; +} + +@synthesize disabledColor = _disabledColor; +- (UIColor *)disabledColor { + if (!_disabledColor) { + _disabledColor = [UIColor mfSilver]; + } + return _disabledColor; +} + +@end diff --git a/MVMCoreUI/Legacy/Views/MFCaretView.h b/MVMCoreUI/Legacy/Views/MFCaretView.h new file mode 100644 index 00000000..e2053f9a --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretView.h @@ -0,0 +1,16 @@ +// +// MFCaretView.h +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import + +@interface MFCaretView : UIView +@property (strong, nonatomic, readonly) UIColor *strokeColor; +- (instancetype)initWithLineWidth:(CGFloat)lineWidth; +- (void)setLineColor:(UIColor *)color; +@end + diff --git a/MVMCoreUI/Legacy/Views/MFCaretView.m b/MVMCoreUI/Legacy/Views/MFCaretView.m new file mode 100644 index 00000000..182f7a74 --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretView.m @@ -0,0 +1,93 @@ +// +// MFCaretView.m +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import "MFCaretView.h" +#import "UIColor+MFConvenience.h" +@interface MFCaretView () +@property (strong, nonatomic, readwrite) UIColor *strokeColor; +@property (nonatomic) NSNumber *lineWidth; + +@end + +@implementation MFCaretView + +- (instancetype)init { + self = [super init]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithLineWidth:(CGFloat)lineWidth { + if (self = [super init]) { + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.lineWidth = @(lineWidth); + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (void)drawRect:(CGRect)rect { + // Drawing Caret + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextClearRect(context, rect); + + CGFloat lineWidth; + if (self.lineWidth) { + lineWidth = self.lineWidth.floatValue; + } else { + lineWidth = self.frame.size.width/2.6; + } + + UIBezierPath *path = [[UIBezierPath alloc] init]; + [path moveToPoint:CGPointMake(lineWidth/2.0, 0.0)]; + [path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height/2.0)]; + [path addLineToPoint:CGPointMake(lineWidth/2.0, self.frame.size.height)]; + [path addLineToPoint:CGPointMake(0.0, self.frame.size.height-lineWidth/2.0)]; + [path addLineToPoint:CGPointMake(self.frame.size.width-lineWidth, self.frame.size.height/2.0)]; + [path addLineToPoint:CGPointMake(0.0, lineWidth/2.0)]; + [path addLineToPoint:CGPointMake(lineWidth/2.0, 0.0)]; + [self.strokeColor setFill]; + [path fill]; + [path closePath]; + [self setBackgroundColor:[UIColor clearColor]]; +} + +- (void)setLineColor:(UIColor *)color { + self.strokeColor = color; + [self setNeedsDisplay]; +} + +@end diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 9150e015..1b2183aa 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -81,6 +81,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import #pragma mark Buttons #import @@ -89,6 +90,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import #pragma mark TextFields #import From fa1c8bad92cd10298803d99ff2c6e93650a3e6ea Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 5 Feb 2020 20:26:34 +0530 Subject: [PATCH 22/29] corner label bug fixes: CXTDT-54851 & CXTDT-4571(see comments) making molecule optional as per one confluence document. Same has been implemented in Android and Server. --- MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift | 6 ++---- MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift index 680e7089..2de9deca 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift @@ -171,10 +171,8 @@ import UIKit guard let model = model as? CornerLabelsModel else { return } if middleView != nil { (middleView as? ModelMoleculeViewProtocol)?.setWithModel(model, delegateObject, additionalData) - } else { - if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject) { - addMiddleView(molecule) - } + } else if let moleculeModel = model.molecule, let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject) { + addMiddleView(molecule) } topLeftLabel.setWithModel(model.topLeftLabel, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift index ce3796bf..f4b67216 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -15,9 +15,9 @@ public class CornerLabelsModel: MoleculeModelProtocol { public var topRightLabel: LabelModel? public var bottomLeftLabel: LabelModel? public var bottomRightLabel: LabelModel? - public var molecule: MoleculeModelProtocol + public var molecule: MoleculeModelProtocol? - init(with molecule: MoleculeModelProtocol) { + init(with molecule: MoleculeModelProtocol?) { self.molecule = molecule } @@ -33,7 +33,7 @@ public class CornerLabelsModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - molecule = try typeContainer.decodeMolecule(codingKey: .molecule) + molecule = try typeContainer.decodeMoleculeIfPresent(codingKey: .molecule) topLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topLeftLabel) topRightLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topRightLabel) bottomLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bottomLeftLabel) From 2e37041e7ec9176925f985ecb13dd7ca8ddc6034 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 5 Feb 2020 20:30:01 +0530 Subject: [PATCH 23/29] Add-ons banner fif for defect: CXTDT-54990 verbiage truncation design 2/3 feedback implemenation --- .../HeadLineBodyCaretLinkImage.swift | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index fc19749a..d5abe33f 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -11,7 +11,6 @@ import Foundation let headlineBody = HeadlineBody(frame: .zero) let caretButton = CaretButton(frame: .zero) let backgroundImageView = MFLoadImageView(pinnedEdges: .all) - var spaceBetweenConstant: CGFloat = 104.0 let maxWidth: CGFloat = 350.0 static let heightConstant: CGFloat = 320.0 var heightConstraint: NSLayoutConstraint? @@ -44,17 +43,17 @@ import Foundation headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true - let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.85) - headLineBodyWidth.priority = .defaultHigh + headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.67).isActive = true + let headLineBodyWidth = headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth) + headLineBodyWidth.priority = UILayoutPriority(250) headLineBodyWidth.isActive = true - headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true //Caret view caretButton.translatesAutoresizingMaskIntoConstraints = false caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true container.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: 0).isActive = true - caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true + caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: PaddingTwo).isActive = true //Background image view backgroundImageView.translatesAutoresizingMaskIntoConstraints = false From 595dc99936ad24e1579b3c9d784d49756f21abfc Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 09:50:03 -0500 Subject: [PATCH 24/29] button minimum caretLink --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 38 +++++------------------ MVMCoreUI/Atoms/Buttons/PillButton.swift | 6 ++-- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 3fcf453a..97f8d55e 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -8,7 +8,7 @@ // -open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, ModelMoleculeViewProtocol { +open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Constants @@ -49,7 +49,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI didSet { changeCaretColor() } } - public func updateView(_ size: CGFloat) { } + public override func updateView(_ size: CGFloat) { + titleLabel?.font = MFStyler.fontB1() + } //------------------------------------------------------ // MARK: - Methods @@ -115,33 +117,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI setTitleColor(disabledColor, for: .disabled) } - @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData) - - guard let dictionary = json else { return } - - if let title = dictionary.optionalStringForKey(KeyTitle) { - setTitle(title, for: .normal) - } - - if let disableButtonAsAny = dictionary[KeyDisableButton], let isDisabled = disableButtonAsAny as? Bool { - isEnabled = !isDisabled - } - - if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String { - backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) - } - - if let enabledColorHex = dictionary["enabledColor"] as? String { - enabledColor = UIColor.mfGet(forHex: enabledColorHex) - } - - if let disabledColorHex = dictionary["disabledColor"] as? String { - disabledColor = UIColor.mfGet(forHex: disabledColorHex) - } - } - - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let caretLinkModel = model as? CaretLinkModel else { return } if let color = caretLinkModel.backgroundColor { backgroundColor = color.uiColor @@ -163,7 +139,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI return .leading } - public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return 10 + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return CARET_VIEW_HEIGHT } } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 0d0a3090..d3d09cee 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -97,9 +97,9 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { switch buttonSize { case .tiny: - return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20 + return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? ButtonHeight.tiny.rawValue default: - return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42 + return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? ButtonHeight.standard.rawValue } } @@ -108,7 +108,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation case .tiny: return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0 default: - return MFSizeObject(standardSize: 102.0, standardiPadPortraitSize: 136.0, iPadProLandscapeSize: 153.0)?.getValueBased(onSize: size) ?? 102.0 + return 151.0 } } From 0d4008dec7210b32582b2360ebc36e6ea273f730 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 09:55:18 -0500 Subject: [PATCH 25/29] CaretLink --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++---- .../Atoms/Buttons/{CaretButton.swift => CaretLink.swift} | 6 +++--- .../HeadLineBodyCaretLinkImage.swift | 9 +-------- MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) rename MVMCoreUI/Atoms/Buttons/{CaretButton.swift => CaretLink.swift} (97%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 752a5445..f97e81aa 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -327,7 +327,7 @@ DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; - DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; + DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; }; DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; }; DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; }; /* End PBXBuildFile section */ @@ -658,7 +658,7 @@ DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; - DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; + DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = ""; }; DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1168,7 +1168,7 @@ isa = PBXGroup; children = ( 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */, - DBC4391A224421A0001AB423 /* CaretButton.swift */, + DBC4391A224421A0001AB423 /* CaretLink.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, @@ -1750,7 +1750,7 @@ 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, C003506123AA94CD00B6AC29 /* Button.swift in Sources */, - DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, + DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretLink.swift similarity index 97% rename from MVMCoreUI/Atoms/Buttons/CaretButton.swift rename to MVMCoreUI/Atoms/Buttons/CaretLink.swift index 405e110f..ca665928 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretLink.swift @@ -1,5 +1,5 @@ // -// CaretButton.swift +// CaretLink.swift // MVMCoreUI // // Created by Kolli, Praneeth on 1/5/18. @@ -8,7 +8,7 @@ // -open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { +open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Constants @@ -148,6 +148,6 @@ open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { } open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return CARET_VIEW_HEIGHT + return 10.5 } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index d5abe33f..2b3567d7 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -9,7 +9,7 @@ import Foundation @objcMembers public class HeadLineBodyCaretLinkImage: Container { let headlineBody = HeadlineBody(frame: .zero) - let caretButton = CaretButton(frame: .zero) + let caretButton = CaretLink(frame: .zero) let backgroundImageView = MFLoadImageView(pinnedEdges: .all) let maxWidth: CGFloat = 350.0 static let heightConstant: CGFloat = 320.0 @@ -66,13 +66,6 @@ import Foundation } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData) - headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) - caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) - } - open override func reset() { super.reset() headlineBody.reset() diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index d3523ccf..8c1a36e3 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -30,7 +30,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretButton.self, viewModelClass: CaretLinkModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self) // Entry Field MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self) From f24485c699ff6cc3c264ce6532a3eb78ab5b9d08 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 11:59:45 -0500 Subject: [PATCH 26/29] fix button order --- .../TwoButtonView.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 31fd6f37..56004de8 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -43,8 +43,8 @@ import UIKit stack.translatesAutoresizingMaskIntoConstraints = false addSubview(stack) - stack.addArrangedSubview(primaryButton) stack.addArrangedSubview(secondaryButton) + stack.addArrangedSubview(primaryButton) NSLayoutConstraint.constraintPinSubview(toSuperview: stack) stack.axis = .horizontal stack.spacing = 10 @@ -107,19 +107,19 @@ import UIKit } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + super.setWithModel(model, delegateObject, additionalData) guard let model = model as? TwoButtonViewModel else { return } - if let primaryModel = model.primaryButton { - showPrimaryButton() - primaryButton.setWithModel(primaryModel, delegateObject, additionalData) - } else { - hidePrimaryButton() - } if let secondaryModel = model.secondaryButton { showSecondaryButton() secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData) } else { hideSecondaryButton() } + if let primaryModel = model.primaryButton { + showPrimaryButton() + primaryButton.setWithModel(primaryModel, delegateObject, additionalData) + } else { + hidePrimaryButton() + } } } From 00b179d8c27f2d9f21e2545f1a8be698de68c5b0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 12:09:35 -0500 Subject: [PATCH 27/29] fix to reuse issue two button view --- .../HorizontalCombinationViews/TwoButtonView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 56004de8..be6228f8 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -54,7 +54,7 @@ import UIKit // MARK: - Stack Manipulation public func showPrimaryButton() { - if primaryButton.superview == nil { + if !stack.arrangedSubviews.contains(primaryButton) { stack.addArrangedSubview(primaryButton) primaryButton.isHidden = false } @@ -64,8 +64,8 @@ import UIKit } public func showSecondaryButton() { - if secondaryButton.superview == nil { - stack.addArrangedSubview(secondaryButton) + if !stack.arrangedSubviews.contains(secondaryButton) { + stack.insertArrangedSubview(secondaryButton, at: 0) secondaryButton.isHidden = false } if primaryButton.superview != nil { From 0dad2aedb1b7610faa9b3cacb256071309296ff4 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 13:00:55 -0500 Subject: [PATCH 28/29] type fix --- MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift index fa7548f3..689a7c62 100644 --- a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift @@ -41,7 +41,7 @@ import Foundation screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) - header = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle) + middle = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle) footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer) } From 61a5932a886c5c8bc27a0ff9e4c9ef7ee3c7acf1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 13:25:52 -0500 Subject: [PATCH 29/29] fixing bug where textfield was not being recognized when resigning responder. --- .../Atoms/TextFields/BaseDropdownEntryField.swift | 2 +- MVMCoreUI/Atoms/TextFields/TextEntryField.swift | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift index 3290c744..70b46866 100644 --- a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift @@ -21,7 +21,7 @@ import UIKit let caret = CaretView() caret.direction = .down caret.lineWidth = 1.5 - caret.isUserInteractionEnabled = true + caret.isUserInteractionEnabled = false caret.heightAnchor.constraint(equalToConstant: 9).isActive = true caret.widthAnchor.constraint(equalToConstant: 16).isActive = true return caret diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 66f3ecd4..def2ae0b 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -25,7 +25,7 @@ import UIKit //-------------------------------------------------- open private(set) var textField: TextField = { - let textField = TextField(frame: .zero) + let textField = TextField() textField.isAccessibilityElement = true textField.setContentCompressionResistancePriority(.required, for: .vertical) textField.font = MFStyler.fontForTextField() @@ -58,7 +58,7 @@ import UIKit get { return super.isEnabled } set (enabled) { super.isEnabled = enabled - + DispatchQueue.main.async { [weak self] in guard let self = self else { return } @@ -99,7 +99,7 @@ import UIKit //-------------------------------------------------- public var validationBlock: ((_ value: String?) -> Bool)? - + //-------------------------------------------------- // MARK: - Delegate Properties //-------------------------------------------------- @@ -169,6 +169,9 @@ import UIKit textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16) textFieldTrailingConstraint?.isActive = true + textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin) + textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd) + let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing)) entryFieldContainer.addGestureRecognizer(tap) @@ -225,7 +228,7 @@ import UIKit /// Validates the text of the entry field. @discardableResult @objc public func validateTextField() -> Bool { - + isValid = validationBlock?(text) ?? true if isValid { @@ -277,7 +280,7 @@ import UIKit guard let model = model as? TextEntryFieldModel else { return } FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - + textColor.enabled = model.enabledTextColor?.uiColor textColor.disabled = model.disabledTextColor?.uiColor text = model.text