From ba8058ccebe76cbb0f363ec759f6ffe31d22324f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Jan 2020 12:58:51 -0500 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 f367b03233f4acb2d7f458351a093bfaf8248044 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 30 Jan 2020 11:41:43 -0500 Subject: [PATCH 5/7] 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 6/7] 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 7/7] 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 {