diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 6fa69289..83a1815f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -113,7 +113,10 @@ 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 */; }; + 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 */; }; + C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; }; C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; }; C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A68023C9830D00BFB94E /* NumberedListModel.swift */; }; C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69323C9909000BFB94E /* DoughnutChartModel.swift */; }; @@ -169,7 +172,6 @@ D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */; }; D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */; }; D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */; }; - D28A838723CCCF6500DFE4FC /* MFTextButton+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838623CCCF6500DFE4FC /* MFTextButton+ModelExtension.swift */; }; D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838823CCCFCB00DFE4FC /* LinkModel.swift */; }; D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */; }; D28A838D23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838C23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift */; }; @@ -210,10 +212,8 @@ D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF16A21E69E1F003B2FB9 /* MFCustomButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF17521E69E1F003B2FB9 /* ButtonDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF16B21E69E1F003B2FB9 /* ButtonDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF16C21E69E1F003B2FB9 /* PrimaryButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D29DF17721E69E1F003B2FB9 /* MFTextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF16D21E69E1F003B2FB9 /* MFTextButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF17021E69E1F003B2FB9 /* MFCustomButton.m */; }; D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF17121E69E1F003B2FB9 /* PrimaryButton.m */; }; - D29DF17C21E69E1F003B2FB9 /* MFTextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF17221E69E1F003B2FB9 /* MFTextButton.m */; }; D29DF18021E69E49003B2FB9 /* MFView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF17E21E69E2E003B2FB9 /* MFView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF18121E69E50003B2FB9 /* MFView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF17F21E69E2E003B2FB9 /* MFView.m */; }; D29DF18221E69E54003B2FB9 /* SeparatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF15921E697DA003B2FB9 /* SeparatorView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -304,6 +304,7 @@ D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; }; D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; }; D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; }; + D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A98223D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.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 */; }; @@ -411,7 +412,10 @@ 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 = ""; }; + 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 = ""; }; + C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = ""; }; C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = ""; }; C695A68023C9830D00BFB94E /* NumberedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberedListModel.swift; sourceTree = ""; }; C695A69323C9909000BFB94E /* DoughnutChartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartModel.swift; sourceTree = ""; }; @@ -466,7 +470,6 @@ D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionListItemModel.swift; sourceTree = ""; }; D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressModel.swift; sourceTree = ""; }; D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollerModel.swift; sourceTree = ""; }; - D28A838623CCCF6500DFE4FC /* MFTextButton+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFTextButton+ModelExtension.swift"; sourceTree = ""; }; D28A838823CCCFCB00DFE4FC /* LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkModel.swift; sourceTree = ""; }; D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModel.swift; sourceTree = ""; }; D28A838C23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PrimaryButton+MoleculeProtocolExtension.swift"; sourceTree = ""; }; @@ -519,10 +522,8 @@ D29DF16A21E69E1F003B2FB9 /* MFCustomButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFCustomButton.h; sourceTree = ""; }; D29DF16B21E69E1F003B2FB9 /* ButtonDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButtonDelegateProtocol.h; sourceTree = ""; }; D29DF16C21E69E1F003B2FB9 /* PrimaryButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimaryButton.h; sourceTree = ""; }; - D29DF16D21E69E1F003B2FB9 /* MFTextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTextButton.h; sourceTree = ""; }; D29DF17021E69E1F003B2FB9 /* MFCustomButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFCustomButton.m; sourceTree = ""; }; D29DF17121E69E1F003B2FB9 /* PrimaryButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrimaryButton.m; sourceTree = ""; }; - D29DF17221E69E1F003B2FB9 /* MFTextButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTextButton.m; sourceTree = ""; }; D29DF17E21E69E2E003B2FB9 /* MFView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFView.h; sourceTree = ""; }; D29DF17F21E69E2E003B2FB9 /* MFView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFView.m; sourceTree = ""; }; D29DF24221E6A176003B2FB9 /* MFTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTextField.m; sourceTree = ""; }; @@ -616,6 +617,7 @@ D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = ""; }; D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = ""; }; D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = ""; }; + D2E2A98223D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EyebrowHeadlineBodyLinkModel.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 = ""; }; @@ -749,6 +751,8 @@ D213347523842FF5008E41B3 /* Views */ = { isa = PBXGroup; children = ( + 94FB966023D797DA003D482B /* MFTextButton.h */, + 94FB966123D797DA003D482B /* MFTextButton.m */, D29DF17E21E69E2E003B2FB9 /* MFView.h */, D29DF17F21E69E2E003B2FB9 /* MFView.m */, D29DF31E21ED0CBA003B2FB9 /* LabelView.h */, @@ -776,8 +780,6 @@ D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, D29DF16A21E69E1F003B2FB9 /* MFCustomButton.h */, D29DF17021E69E1F003B2FB9 /* MFCustomButton.m */, - D29DF16D21E69E1F003B2FB9 /* MFTextButton.h */, - D29DF17221E69E1F003B2FB9 /* MFTextButton.m */, D29DF16C21E69E1F003B2FB9 /* PrimaryButton.h */, D29DF17121E69E1F003B2FB9 /* PrimaryButton.m */, D29DF25821E6A22D003B2FB9 /* MFButtonProtocol.h */, @@ -822,6 +824,7 @@ 01EB368D23609801006832FA /* HeadlineBodyModel.swift */, D2A638FC22CA98280052ED1F /* HeadlineBody.swift */, D22479952316AF6D003FCCF9 /* HeadlineBodyTextButton.swift */, + D2E2A98223D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift */, D27CD40F2339057800C1DC07 /* EyebrowHeadlineBodyLink.swift */, D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */, C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */, @@ -1124,8 +1127,8 @@ D282AACA2243C61700C46919 /* ButtonView.swift */, D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, D28A838C23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift */, - D28A838623CCCF6500DFE4FC /* MFTextButton+ModelExtension.swift */, D28A837623C79FC600DFE4FC /* MFCustomButton+ActionModel.swift */, + C07065C32395677300FBF997 /* Link.swift */, ); path = Buttons; sourceTree = ""; @@ -1364,6 +1367,7 @@ D29DF2CE21E7C104003B2FB9 /* MFLoadingViewController.h in Headers */, 0A21DB84235E06EF00C160A2 /* MFTextField.h in Headers */, D29DF12A21E6851E003B2FB9 /* MVMCoreUITopAlertView.h in Headers */, + 94FB966223D797DA003D482B /* MFTextButton.h in Headers */, D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */, D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */, D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */, @@ -1376,7 +1380,6 @@ D29DF18221E69E54003B2FB9 /* SeparatorView.h in Headers */, D29DF26E21E6AA0B003B2FB9 /* FLAnimatedImage.h in Headers */, D29DF11621E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.h in Headers */, - D29DF17721E69E1F003B2FB9 /* MFTextButton.h in Headers */, 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */, D29DF16221E69996003B2FB9 /* MFViewController.h in Headers */, 0A21DB88235E06EF00C160A2 /* MFMdnTextField.h in Headers */, @@ -1492,6 +1495,7 @@ D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, + C07065C42395677300FBF997 /* Link.swift in Sources */, D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */, @@ -1520,10 +1524,10 @@ D224798C231450C8003FCCF9 /* HeadlineBodySwitch.swift in Sources */, 017BEB442362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift in Sources */, 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */, - D29DF17C21E69E1F003B2FB9 /* MFTextButton.m in Sources */, 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */, 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */, D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */, + D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, D260106323D0C05000764D80 /* StackItemModel.swift in Sources */, @@ -1540,7 +1544,6 @@ D28A838D23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift in Sources */, D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */, D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, - D28A838723CCCF6500DFE4FC /* MFTextButton+ModelExtension.swift in Sources */, C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */, 014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */, D260106123D0C02A00764D80 /* StackItemModelProtocol.swift in Sources */, @@ -1583,6 +1586,7 @@ C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, + 94FB966323D797DA003D482B /* MFTextButton.m in Sources */, D260105323CEA61600764D80 /* ToggleModel.swift in Sources */, 014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */, 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/Link.swift b/MVMCoreUI/Atoms/Buttons/Link.swift new file mode 100644 index 00000000..4a498fdd --- /dev/null +++ b/MVMCoreUI/Atoms/Buttons/Link.swift @@ -0,0 +1,88 @@ +// +// Link.swift +// MVMCoreUI +// +// Created by Robinson, Blake on 11/26/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + + +@objcMembers open class Link: Button { + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func draw(_ rect: CGRect) { + + guard let textRect = titleLabel?.frame else { return } + + let context = UIGraphicsGetCurrentContext() + + // Set line to the same color as the text + if let color = titleLabel?.textColor?.cgColor { + context?.setStrokeColor(color) + } + + // x should be according to the text, not the button + let x = textRect.origin.x + + // Line is 1 point below the text + let y = textRect.origin.y + textRect.size.height + 1 + + context?.move(to: CGPoint(x: x, y: y)) + context?.addLine(to: CGPoint(x: x + textRect.size.width, y: y)) + context?.strokePath() + } + + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? LinkModel else { return } + setTitle(model.title, for: .normal) + setTitleColor(model.textColor.uiColor, for: .normal) + setTitleColor(model.disabledColor.uiColor, for: .disabled) + isEnabled = model.enabled + set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) + } + + public static func estimatedHeight(forRow molecule: ModuleMoleculeModel?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 31.0 + } +} + +// MARK: - MVMCoreViewProtocol +extension Link { + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + var width = size + if MVMCoreGetterUtility.fequal(a: Float(CGFloat.leastNormalMagnitude), b: Float(size)) { + width = MVMCoreUIUtility.getWidth() + } + self.titleLabel?.font = MFStyler.fontB2(forWidth: width) + } + } + + public override func setupView() { + super.setupView() + backgroundColor = .clear + contentMode = .redraw + setTitleColor(.mvmBlack, for: .normal) + setTitleColor(.mvmCoolGray6, for: .disabled) + titleLabel?.numberOfLines = 1 + titleLabel?.lineBreakMode = .byTruncatingTail + titleLabel?.textAlignment = .left + contentHorizontalAlignment = .left + } +} + +// MARK: - MVMCoreUIViewConstrainingProtocol +extension Link: MVMCoreUIViewConstrainingProtocol { + + public func alignment() -> UIStackView.Alignment { + return .leading + } +} diff --git a/MVMCoreUI/Atoms/Buttons/LinkModel.swift b/MVMCoreUI/Atoms/Buttons/LinkModel.swift index 0c797b21..28e00d60 100644 --- a/MVMCoreUI/Atoms/Buttons/LinkModel.swift +++ b/MVMCoreUI/Atoms/Buttons/LinkModel.swift @@ -14,7 +14,8 @@ public class LinkModel: MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabled = true - public var textColor = Color(uiColor: .mfTextButton()) + public var textColor = Color(uiColor: .mvmBlack) + public var disabledColor = Color(uiColor: .mvmCoolGray6) public init(title: String, action: ActionModelProtocol) { self.title = title @@ -27,6 +28,7 @@ public class LinkModel: MoleculeModelProtocol { case action case enabled case textColor + case disabledColor } required public init(from decoder: Decoder) throws { @@ -40,6 +42,10 @@ public class LinkModel: MoleculeModelProtocol { if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) { textColor = color } + + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { + disabledColor = color + } } public func encode(to encoder: Encoder) throws { @@ -49,5 +55,6 @@ public class LinkModel: MoleculeModelProtocol { try container.encodeModel(action, forKey: .action) try container.encode(enabled, forKey: .enabled) try container.encode(textColor, forKey: .textColor) + try container.encode(disabledColor, forKey: .disabledColor) } } diff --git a/MVMCoreUI/Atoms/Buttons/MFTextButton+ModelExtension.swift b/MVMCoreUI/Atoms/Buttons/MFTextButton+ModelExtension.swift deleted file mode 100644 index dc5399ef..00000000 --- a/MVMCoreUI/Atoms/Buttons/MFTextButton+ModelExtension.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// MFTextButton_ModelExtension.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 1/13/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - -// temporary until link is finished -extension MFTextButton: ModelMoleculeViewProtocol { - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - guard let model = model as? LinkModel else { return } - setTitle(model.title, for: .normal) - setTitleColor(model.textColor.uiColor, for: .normal) - isEnabled = model.enabled - backgroundColor = model.backgroundColor?.uiColor - set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) - } -} diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index d0ce4c1b..7909d1dd 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -public typealias ButtonBlock = (Button) -> () +public typealias ButtonAction = (Button) -> () @objcMembers open class Button: UIButton, MFButtonProtocol, ModelMoleculeViewProtocol { //-------------------------------------------------- @@ -17,7 +17,7 @@ public typealias ButtonBlock = (Button) -> () private var initialSetupPerformed = false - private var buttonBlock: ButtonBlock? + private var buttonAction: ButtonAction? //-------------------------------------------------- // MARK: - Delegate @@ -60,19 +60,20 @@ public typealias ButtonBlock = (Button) -> () // MARK: - Methods //-------------------------------------------------- - public func addBlock( event: Event, _ buttonBlock: @escaping ButtonBlock) { - self.buttonBlock = buttonBlock - addTarget(self, action: #selector(callBlock(_:)), for: event) + public func addActionBlock( event: Event, _ buttonBlock: @escaping ButtonAction) { + self.buttonAction = buttonBlock + addTarget(self, action: #selector(callActionBlock(_:)), for: event) } - func callBlock(_ sender: Button) { - buttonBlock?(self) + func callActionBlock(_ sender: Button) { + buttonAction?(self) } - public func setWithAction(_ actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + public func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { self.actionModel = actionModel buttonDelegate = delegateObject?.buttonDelegate - addBlock(event: .touchUpInside) { [weak self] sender in + + addActionBlock(event: .touchUpInside) { [weak self] sender in guard let self = self else { return } if let data = try? actionModel.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], @@ -103,6 +104,7 @@ public typealias ButtonBlock = (Button) -> () } } + // MARK: - MVMCoreViewProtocol extension Button: MVMCoreViewProtocol { diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index 3f5d13aa..77a479c5 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -8,22 +8,12 @@ import UIKit -struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { - static var identifier: String = "eyebrowHeadlineBodyLink" - var backgroundColor: Color? - - public var eyeBrow: LabelModel? - public var headline: LabelModel? - public var body: LabelModel? - public var link: LineModel? -} - @objcMembers open class EyebrowHeadlineBodyLink: Container { let stack = Stack(frame: .zero) let eyebrow = Label.commonLabelB3(true) let headline = Label.commonLabelB1(true) let body = Label.commonLabelB2(true) - let link = MFTextButton(nil, constrainHeight: false, forWidth: MVMCoreUIUtility.getWidth()) + let link = Link() var casteModel: EyebrowHeadlineBodyLinkModel? { get { return model as? EyebrowHeadlineBodyLinkModel } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift new file mode 100644 index 00000000..e9341535 --- /dev/null +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -0,0 +1,19 @@ +// +// EyebrowHeadlineBodyLinkModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 1/22/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { + static var identifier: String = "eyebrowHeadlineBodyLink" + var backgroundColor: Color? + + public var eyeBrow: LabelModel? + public var headline: LabelModel? + public var body: LabelModel? + public var link: LinkModel? +} diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index b9a847ac..54ec832c 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -10,42 +10,14 @@ import Foundation @objcMembers public class MoleculeObjectMapping: NSObject { public static func registerObjects() { + // Stacks MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: MoleculeStackModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Stack.self, viewModelClass: StackModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self) + + // Label MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeaderView.self, viewModelClass: HeaderModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) - ModelRegistry.register(MoleculeStackItemModel.self) - ModelRegistry.register(TextFieldModel.self) - ModelRegistry.register(ProgressBarModel.self) - ModelRegistry.register(MultiProgressBarModel.self) - ModelRegistry.register(CaretViewModel.self) - ModelRegistry.register(DashLineModel.self) - ModelRegistry.register(ImageViewModel.self) - ModelRegistry.register(TabsModel.self) - ModelRegistry.register(ScrollerModel.self) - ModelRegistry.register(CornerLabelsModel.self) - ModelRegistry.register(LineModel.self) - ModelRegistry.register(CircleProgressModel.self) - ModelRegistry.register(HeadlineBodyCaretLinkImageModel.self) - ModelRegistry.register(ToggleModel.self) - // buttons - ModelRegistry.register(ButtonModel.self) - ModelRegistry.register(TwoButtonViewModel.self) - ModelRegistry.register(LinkModel.self) - ModelRegistry.register(CaretLinkModel.self) - // list items - ModelRegistry.register(ListItemModel.self) - ModelRegistry.register(DropDownListItemModel.self) - ModelRegistry.register(AccordionListItemModel.self) - ModelRegistry.register(TabsListItemModel.self) - //need to move labelattributemodel to different method ModelRegistry.register(LabelAttributeFontModel.self) ModelRegistry.register(LabelAttributeColorModel.self) @@ -53,16 +25,83 @@ import Foundation ModelRegistry.register(LabelAttributeUnderlineModel.self) ModelRegistry.register(LabelAttributeStrikeThroughModel.self) ModelRegistry.register(LabelAttributeActionModel.self) + + // Buttons + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PrimaryButton.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) + + // Entry Field + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextFieldModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MdnEntryField.self, viewModelClass: MdnEntryFieldModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DigitEntryField.self, viewModelClass: DigitEntryFieldModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self) + + // Other Atoms + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MFLoadImageView.self, viewModelClass: ImageViewModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self) - // - //ModelRegistry.register(ModuleMoleculeModel.self) - ModelRegistry.register(LeftRightLabelModel.self) - ModelRegistry.register(CaretViewModel.self) - ModelRegistry.register(CaretLinkModel.self) - ModelRegistry.register(LabelToggleModel.self) - ModelRegistry.register(DoughnutChartModel.self) - ModelRegistry.register(NumberedListModel.self) - ModelRegistry.register(UnOrderedListModel.self) - ModelRegistry.register(HeadlineBodyToggleModel.self) + // Horizontal Combination Molecules + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) + + // Vertical Combination Molecules + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self) + + // Left Right Molecules + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: LeftRightLabelView.self, viewModelClass: LeftRightLabelModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: LabelSwitch.self, viewModelClass: LabelToggleModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodySwitch.self, viewModelClass: HeadlineBodyToggleModel.self) + + // List items + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: ListItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self) + + // Other Items + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: CarouselItemModel.self) + + // Other Container Molecules + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeaderView.self, viewModelClass: HeaderModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self) + + // Other Molecules + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self) + + // Other Organisms + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self) + + // TODO: Need model + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(DigitEntryField.self, forKey: "digitTextField" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(DateDropdownEntryField.self, forKey: "dateDropdownEntryField" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(Checkbox.self, forKey: "checkbox" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(CheckboxWithLabelView.self, forKey: "checkboxLabel" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(RadioButton.self, forKey: "radioButton" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(RadioButtonLabel.self, forKey: "radioButtonLabel" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(ActionDetailWithImage.self, forKey: "actionDetailWithImage" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(ImageHeadlineBody.self, forKey: "imageHeadlineBody" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(HeadlineBodyTextButton.self, forKey: "headlineBodyLink" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(HeadlineBodyTextButtonSwitch.self, forKey: "headlineBodyLinkToggle" as NSString) + MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(HeadlineBodyButton.self, forKey: "headlineBodyButton" as NSString) + + // TODO: Need View + ModelRegistry.register(TabsModel.self) } } diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.h b/MVMCoreUI/Utility/MVMCoreUIConstants.h index e5587745..4c0a3553 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.h +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.h @@ -22,6 +22,7 @@ extern NSString * const KeyDisableButton; extern NSString * const KeyValue; extern NSString * const KeyLabel; extern NSString * const KeyDisable; +extern NSString * const KeyEnabled; extern NSString * const KeyFieldName; extern NSString * const KeyHideMainMenu; diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.m b/MVMCoreUI/Utility/MVMCoreUIConstants.m index 6211cfee..5f5a9a45 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.m +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.m @@ -21,6 +21,7 @@ NSString * const KeyDisableButton = @"disableAction"; NSString * const KeyValue = @"value"; NSString * const KeyLabel = @"label"; NSString * const KeyDisable = @"disable"; +NSString * const KeyEnabled = @"enabled"; NSString * const KeyFieldName = @"fieldName"; NSString * const KeyFieldKey = @"fieldKey"; NSString * const KeyRequired = @"required";