Merge branch 'develop' into feature/list_threecolumn_datausage_listitem

* develop: (27 commits)
  correcting spacing issue
  not needed
  required
  required now works due to changes
  changes to improve
  removed unneded optional wrapper
  toggle changes
  update parentheses
  fix for CXTDT_74295
  disable tap if radio is disabled
  small fix encoding numbered list
  remove previous items
  corner  labels defect fix
  merge
  remove bad remove items
  reuse issue fix
  remove unneeded comment
  Encode fix
  MoleculeStack
  Key changes
  ...
This commit is contained in:
Kruthika KP 2020-04-22 12:21:43 +05:30
commit 1d9e9761f1
41 changed files with 321 additions and 366 deletions

View File

@ -61,7 +61,6 @@
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* MoleculeListItemModel.swift */; };
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368B23609801006832FA /* MoleculeStackModel.swift */; };
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; };
@ -152,9 +151,9 @@
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; };
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */; };
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; };
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* Wheel.swift */; };
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */; };
943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; };
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94382085243238D100B43AF3 /* WebViewModel.swift */; };
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */; };
@ -238,6 +237,7 @@
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; };
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; };
D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; };
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */; };
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; };
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */; };
D21B7F75243BAC8900051ABF /* CarouselItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F74243BAC8900051ABF /* CarouselItem.swift */; };
@ -298,7 +298,7 @@
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; };
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837E23CCA96400DFE4FC /* TabsModel.swift */; };
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */; };
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */; };
D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838223CCBD3F00DFE4FC /* WheelModel.swift */; };
D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */; };
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838823CCCFCB00DFE4FC /* LinkModel.swift */; };
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */; };
@ -406,7 +406,6 @@
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */; };
D29E28DA23D21AFA00ACEA85 /* StringAndMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */; };
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */; };
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */; };
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */; };
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */; };
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* MoleculeHeaderView.swift */; };
@ -510,7 +509,6 @@
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
01EB368923609801006832FA /* MoleculeListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeListItemModel.swift; sourceTree = "<group>"; };
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = "<group>"; };
01EB368B23609801006832FA /* MoleculeStackModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackModel.swift; sourceTree = "<group>"; };
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; };
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; };
@ -593,8 +591,8 @@
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeListTemplate.swift; sourceTree = "<group>"; };
942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeStackTemplate.swift; sourceTree = "<group>"; };
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
943784F3236B77BB006A1E82 /* Wheel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Wheel.swift; sourceTree = "<group>"; };
943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WheelAnimationHandler.swift; sourceTree = "<group>"; };
943820832432382400B43AF3 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
94382085243238D100B43AF3 /* WebViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewModel.swift; sourceTree = "<group>"; };
9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarModel.swift; sourceTree = "<group>"; };
@ -677,6 +675,7 @@
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = "<group>"; };
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = "<group>"; };
D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemModelProtocol.swift; sourceTree = "<group>"; };
D21B7F74243BAC8900051ABF /* CarouselItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItem.swift; sourceTree = "<group>"; };
@ -736,7 +735,7 @@
D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = "<group>"; };
D28A837E23CCA96400DFE4FC /* TabsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsModel.swift; sourceTree = "<group>"; };
D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionListItemModel.swift; sourceTree = "<group>"; };
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressModel.swift; sourceTree = "<group>"; };
D28A838223CCBD3F00DFE4FC /* WheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WheelModel.swift; sourceTree = "<group>"; };
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollerModel.swift; sourceTree = "<group>"; };
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkModel.swift; sourceTree = "<group>"; };
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModel.swift; sourceTree = "<group>"; };
@ -859,7 +858,6 @@
D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeView.swift; sourceTree = "<group>"; };
D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeModel.swift; sourceTree = "<group>"; };
D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerHelper.swift; sourceTree = "<group>"; };
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackTemplate.swift; sourceTree = "<group>"; };
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackCenteredTemplate.swift; sourceTree = "<group>"; };
D2A514662213885800345BFB /* MoleculeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderView.swift; sourceTree = "<group>"; };
@ -1313,8 +1311,7 @@
D260105A23D0BB7100764D80 /* StackModelProtocol.swift */,
D260106423D0CEA700764D80 /* StackModel.swift */,
D260105C23D0BCD400764D80 /* Stack.swift */,
01EB368B23609801006832FA /* MoleculeStackModel.swift */,
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */,
D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */,
012A88AE238C626E00FE3DA1 /* CarouselModel.swift */,
D2A6390022CBB1820052ED1F /* Carousel.swift */,
);
@ -1715,9 +1712,9 @@
94C2D9822386F3E30006CF46 /* Label */,
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */,
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
943784F3236B77BB006A1E82 /* GraphView.swift */,
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
D28A838223CCBD3F00DFE4FC /* WheelModel.swift */,
943784F3236B77BB006A1E82 /* Wheel.swift */,
943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */,
D260105223CEA61600764D80 /* ToggleModel.swift */,
0AA33B392398524F0067DD0F /* Toggle.swift */,
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */,
@ -2083,7 +2080,7 @@
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */,
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
@ -2110,6 +2107,7 @@
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */,
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */,
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */,
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */,
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
@ -2165,7 +2163,6 @@
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */,
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */,
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */,
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */,
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */,
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
@ -2192,7 +2189,6 @@
0A21DB85235E06EF00C160A2 /* MFTextField.m in Sources */,
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */,
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */,
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */,
8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */,
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */,
@ -2208,8 +2204,8 @@
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */,
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */,
D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */,
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */,
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
DBEFFA04225A829700230692 /* Label.swift in Sources */,
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */,
@ -2374,7 +2370,7 @@
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */,

View File

@ -13,5 +13,4 @@ import UIKit
public var actionType: String
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
public var title: String?
}

View File

@ -22,8 +22,6 @@ public class ActionOpenPanelModel: ActionModelProtocol {
public var panel: Panel
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
// Temporary fix till server changes
public var title: String?
public init(panel: Panel) {
self.panel = panel

View File

@ -14,8 +14,6 @@ import Foundation
public var pageType: String
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
// Temporary fix till server changes
public var title: String?
public init(pageType: String) {
self.pageType = pageType

View File

@ -25,7 +25,7 @@ open class ExternalLink: Link {
guard let model = model as? ExternalLinkModel else { return }
exportImageView?.tintColor = model.textColor.uiColor
exportImageView?.tintColor = model.enabledColor.uiColor
}
//--------------------------------------------------

View File

@ -52,7 +52,7 @@ import UIKit
guard let model = model as? LinkModel else { return }
setTitle(model.title, for: .normal)
setTitleColor(model.textColor.uiColor, for: .normal)
setTitleColor(model.enabledColor.uiColor, for: .normal)
setTitleColor(model.disabledColor.uiColor, for: .disabled)
isEnabled = model.enabled
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -21,7 +21,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
public var title: String
public var action: ActionModelProtocol
public var enabled = true
public var textColor = Color(uiColor: .mvmBlack)
public var enabledColor = Color(uiColor: .mvmBlack)
public var disabledColor = Color(uiColor: .mvmCoolGray6)
//--------------------------------------------------
@ -43,7 +43,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
case title
case action
case enabled
case textColor
case enabledColor
case disabledColor
}
@ -60,8 +60,8 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) {
textColor = color
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
enabledColor = color
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
@ -76,7 +76,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeModel(action, forKey: .action)
try container.encode(enabled, forKey: .enabled)
try container.encode(textColor, forKey: .textColor)
try container.encode(enabledColor, forKey: .enabledColor)
try container.encode(disabledColor, forKey: .disabledColor)
}
}

View File

@ -90,6 +90,9 @@ import UIKit
/// The action performed when tapped.
func tapAction() {
if !isEnabled {
return
}
if let radioButtonModel = radioButtonSelectionHelper {
radioButtonModel.selected(self)
} else {

View File

@ -258,12 +258,12 @@ import UIKit
title = model.title
feedback = model.feedback
errorMessage = model.errorMessage
isEnabled = model.isEnabled
isEnabled = model.enabled
if let isLocked = model.isLocked {
if let isLocked = model.locked {
self.isLocked = isLocked
} else if let isSelected = model.isSelected{
} else if let isSelected = model.selected {
self.isSelected = isSelected
}
}

View File

@ -9,7 +9,7 @@
import Foundation
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol {
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
@ -23,9 +23,9 @@ import Foundation
public var title: String?
public var feedback: String?
public var errorMessage: String = ""
public var isEnabled: Bool = true
public var isLocked: Bool?
public var isSelected: Bool?
public var enabled: Bool = true
public var locked: Bool?
public var selected: Bool?
public var text: String?
public var fieldKey: String?
@ -52,14 +52,12 @@ import Foundation
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case title = "label"
case isEnabled
case title
case enabled
case feedback
case errorMessage = "errorMsg"
case isLocked
case isSelected
case isValid
case isRequired = "required"
case errorMessage
case locked
case selected
case text
case fieldKey
case groupName
@ -84,10 +82,9 @@ import Foundation
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? ""
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
isLocked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isLocked)
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
baseValue = text
@ -104,12 +101,11 @@ import Foundation
try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(feedback, forKey: .feedback)
try container.encode(errorMessage, forKey: .errorMessage)
try container.encode(isEnabled, forKey: .isEnabled)
try container.encode(isLocked, forKey: .isLocked)
try container.encode(isSelected, forKey: .isSelected)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(isValid, forKey: .isValid)
try container.encode(enabled, forKey: .enabled)
try container.encode(locked, forKey: .locked)
try container.encode(selected, forKey: .selected)
try container.encodeIfPresent(text, forKey: .text)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
}
}

View File

@ -314,14 +314,7 @@ import UIKit
break
}
if let regex = model.regex, !regex.isEmpty {
validationBlock = { enteredValue in
guard let value = enteredValue else { return false }
return MVMCoreUIUtility.validate(value, withRegularExpression: regex)
}
} else {
defaultValidationBlock()
}
defaultValidationBlock()
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate

View File

@ -27,7 +27,6 @@
public var enabledTextColor: Color?
public var disabledTextColor: Color?
public var type: EntryType?
public var regex: String?
//--------------------------------------------------
// MARK: - Keys
@ -40,7 +39,6 @@
case enabledTextColor
case disabledTextColor
case type
case regex
}
//--------------------------------------------------
@ -55,7 +53,6 @@
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex)
}
public override func encode(to encoder: Encoder) throws {
@ -67,6 +64,5 @@
try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor)
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
try container.encodeIfPresent(type, forKey: .type)
try container.encodeIfPresent(regex, forKey: .regex)
}
}

View File

@ -14,8 +14,8 @@ import Foundation
// MARK: - Outlets
//------------------------------------------------------
let leftTextLabel = Label.commonLabelB1(true)
let rightTextLabel = Label.commonLabelB1(true)
let leftTextLabel = Label.createLabelBoldBodySmall(true)
let rightTextLabel = Label.createLabelBoldBodySmall(true)
//------------------------------------------------------
// MARK: - Constraints
@ -23,6 +23,29 @@ import Foundation
var rightTextLabelLeading: NSLayoutConstraint?
var leftTextLabelTrailing: NSLayoutConstraint?
var rightTextLabelTrailing: NSLayoutConstraint?
private func constrainLeftLabelOnly() {
deactivateMiddleConstraint()
leftTextLabelTrailing?.isActive = false
leftTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor)
leftTextLabelTrailing?.isActive = true
}
private func constrainRightLabelOnly() {
deactivateMiddleConstraint()
rightTextLabelLeading?.isActive = false
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
rightTextLabelLeading?.isActive = true
}
private func deactivateMiddleConstraint() {
leftTextLabelTrailing?.isActive = false
rightTextLabelLeading?.isActive = false
}
//------------------------------------------------------
// MARK: - Initialization
@ -43,8 +66,6 @@ import Foundation
override open func setupView() {
super.setupView()
guard subviews.isEmpty else { return }
addSubview(leftTextLabel)
addSubview(rightTextLabel)
@ -67,7 +88,7 @@ import Foundation
// Resolves text layout issues found between both dynamically sized labels, number is not exact but performs as required.
if leftTextLabel.hasText && rightTextLabel.hasText {
let padding = MFStyler.defaultHorizontalPadding(forSize: size) * 2
let maximumTextWidth = (size - (padding + 16)) * 0.4
let maximumTextWidth = (size - (padding + Padding.Four)) * 0.4
// Subtracting 10 resolves issues of SE and iPad
rightTextLabel.preferredMaxLayoutWidth = round(maximumTextWidth) - 10
} else {
@ -84,57 +105,38 @@ import Foundation
leftTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
leftTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
let leftTextBottom = leftTextLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
let leftTextBottom = bottomAnchor.constraint(equalTo: leftTextLabel.bottomAnchor)
leftTextBottom.priority = UILayoutPriority(249)
leftTextBottom.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: leftTextLabel.bottomAnchor).isActive = true
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor, constant: 16)
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor, constant: Padding.Four)
rightTextLabelLeading?.isActive = true
rightTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
let rightLayout = layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightTextLabel.trailingAnchor)
rightLayout.priority = UILayoutPriority(rawValue: 995)
rightLayout.isActive = true
let rightTextBottom = rightTextLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
rightTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightTextLabel.trailingAnchor)
rightTextLabelTrailing?.isActive = true
let rightTextBottom = bottomAnchor.constraint(equalTo: rightTextLabel.bottomAnchor)
rightTextBottom.priority = UILayoutPriority(rawValue: 249)
rightTextBottom.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: rightTextLabel.bottomAnchor).isActive = true
let leftTextWidth = leftTextLabel.widthAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.widthAnchor, multiplier: 0.6)
let leftTextWidth = leftTextLabel.widthAnchor.constraint(equalTo: layoutMarginsGuide.widthAnchor, multiplier: 0.6)
leftTextWidth.priority = UILayoutPriority(rawValue: 995)
leftTextWidth.isActive = true
let rightTextWidth = rightTextLabel.widthAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.widthAnchor, multiplier: 0.4)
rightTextWidth.priority = UILayoutPriority(rawValue: 906)
let rightTextWidth = rightTextLabel.widthAnchor.constraint(equalTo: layoutMarginsGuide.widthAnchor, multiplier: 0.4)
rightTextWidth.priority = UILayoutPriority(rawValue: 995)
rightTextWidth.isActive = true
leftTextLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal)
rightTextLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal)
leftTextLabel.setContentHuggingPriority(.required, for: .vertical)
rightTextLabel.setContentHuggingPriority(.required, for: .vertical)
rightTextLabel.setContentHuggingPriority(.required, for: .horizontal)
leftTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
rightTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
rightTextLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 902), for: .horizontal)
}
private func constrainLeftLabel() {
deactivateMiddleConstraint()
leftTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor)
leftTextLabelTrailing?.isActive = true
}
private func constrainRightLabel() {
deactivateMiddleConstraint()
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
rightTextLabelLeading?.isActive = true
rightTextLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
}
override open func reset() {
@ -144,31 +146,31 @@ import Foundation
constrainBothLabels()
leftTextLabel.text = ""
rightTextLabel.text = ""
leftTextLabel.textAlignment = .left
rightTextLabel.textAlignment = .right
backgroundColor = nil
}
private func deactivateMiddleConstraint() {
leftTextLabelTrailing?.isActive = false
rightTextLabelLeading?.isActive = false
}
//------------------------------------------------------
// MARK: - Atomization
//------------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let leftRightLabelModel = model as? LeftRightLabelModel else {
return
}
guard let leftRightLabelModel = model as? LeftRightLabelModel else { return }
leftTextLabel.set(with: leftRightLabelModel.leftText, delegateObject, additionalData)
rightTextLabel.setOptional(with: leftRightLabelModel.rightText, delegateObject, additionalData)
// Label defaults to .left if no textAlignment value is provided in model.
rightTextLabel.textAlignment = leftRightLabelModel.rightText?.textAlignment ?? .right
if !leftTextLabel.hasText {
constrainRightLabel()
constrainRightLabelOnly()
} else if !rightTextLabel.hasText {
constrainLeftLabel()
constrainLeftLabelOnly()
}
}
}

View File

@ -9,39 +9,27 @@
import UIKit
@objcMembers open class MultiProgress: View {
private let stack = Stack<StackModel>()
var multiProgressModel: MultiProgressBarModel? {
get { return model as? MultiProgressBarModel }
}
///passing value to progressList creates corresponding progress bars
var progressList: Array<SingleProgressBarModel>? {
didSet {
for subview in subviews {
subview.removeFromSuperview()
}
guard (progressList?.count ?? 0) > 0 else {
return
}
var previous: UIView?
for progressObject in progressList! {
guard progressObject.progress > 0.0 else {
continue
}
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
addSubview(view)
view.backgroundColor = progressObject.progressColor.uiColor
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)
}
}
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.init(frame: .zero)
set(with: model, delegateObject, additionalData)
}
var roundedRect: Bool = false {
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
public override init(frame: CGRect) {
super.init(frame: frame)
}
var roundedCorners: Bool = false {
didSet {
if roundedRect {
if roundedCorners {
layer.cornerRadius = (thicknessConstraint?.constant ?? defaultHeight)/2
} else {
layer.cornerRadius = 0
@ -57,28 +45,53 @@ import UIKit
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .mfLightSilver()
clipsToBounds = true
addSubview(stack)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
stack.backgroundColor = backgroundColor
stack.contentView.backgroundColor = .white
stack.model = StackModel(molecules: [], axis: .horizontal, spacing: 2)
stack.stackModel?.horizontalAlignment = .leading
if thicknessConstraint == nil {
thicknessConstraint = heightAnchor.constraint(equalToConstant: defaultHeight)
thicknessConstraint?.isActive = true
}
}
/// Creates the bars
open func set(with progressList: Array<SingleProgressBarModel>, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
stack.removeAllItemViews()
guard let stackModel = stack.stackModel else { return }
var views: [StackItem] = []
var models: [StackItemModel] = []
for progressObject in progressList {
guard progressObject.percent > 0.0 else { continue }
let model = StackItemModel(percent: Int(progressObject.percent), horizontalAlignment: .fill, verticalAlignment: .fill)
model.backgroundColor = progressObject.color
models.append(model)
views.append(StackItem())
}
stack.stackItems = views
stackModel.molecules = models
stack.set(with: stackModel, delegateObject, additionalData)
}
//MARK: - MoleculeViewProtocol
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let multiProgressModel = multiProgressModel else {
return
}
roundedRect = multiProgressModel.roundedRect ?? false
guard let multiProgressModel = multiProgressModel else { return }
roundedCorners = multiProgressModel.roundedCorners ?? false
thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight
progressList = multiProgressModel.progressList
stack.model?.backgroundColor = model.backgroundColor
set(with: multiProgressModel.progressList, delegateObject, additionalData)
}
open override func reset() {
super.reset()
backgroundColor = .mfLightSilver()
progressList = nil
stack.reset()
set(with: [], nil, nil)
}
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {

View File

@ -9,12 +9,12 @@
import Foundation
@objcMembers public class SingleProgressBarModel: Codable {
@Percent var progress: CGFloat
var progressColor: Color
@Percent var percent: CGFloat
var color: Color
init(_ progress: CGFloat, color: Color) {
self.progress = progress
self.progressColor = color
init(_ percent: CGFloat, color: Color) {
self.percent = percent
self.color = color
}
}
@ -23,13 +23,13 @@ import Foundation
public var progressList: [SingleProgressBarModel]
public var backgroundColor: Color?
public var thickness: CGFloat?
public var roundedRect: Bool?
public var roundedCorners: Bool?
private enum CodingKeys: String, CodingKey {
case moleculeName
case progressList
case thickness
case roundedRect
case roundedCorners
case backgroundColor
}
@ -42,7 +42,7 @@ import Foundation
progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
roundedRect = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedRect)
roundedCorners = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedCorners)
}
public func encode(to encoder: Encoder) throws {
@ -50,7 +50,7 @@ import Foundation
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(progressList, forKey: .progressList)
try container.encodeIfPresent(thickness, forKey: .thickness)
try container.encodeIfPresent(roundedRect, forKey: .roundedRect)
try container.encodeIfPresent(roundedCorners, forKey: .roundedCorners)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
}
}

View File

@ -14,7 +14,7 @@ import Foundation
var thickness: CGFloat = 8.0 {
willSet(newValue) {
heightAnchor.constraint(equalToConstant: newValue).isActive = true
if progressBarModel?.isRounded ?? false {
if progressBarModel?.roundedCorners ?? false {
layer.cornerRadius = newValue/2.0
} else {
progressViewStyle = .bar
@ -52,12 +52,11 @@ import Foundation
//MARK: - MoleculeViewProtocol
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let progressBarModel = model as? ProgressBarModel else {
return
}
guard let progressBarModel = model as? ProgressBarModel else { return }
self.progressBarModel = progressBarModel
thickness = progressBarModel.thickness ?? 8
progress = Float((progressBarModel.percent)/100.0)
progressTintColor = progressBarModel.progressColor.uiColor
progressTintColor = progressBarModel.color.uiColor
if let backgroundColor = progressBarModel.backgroundColor {
trackTintColor = backgroundColor.uiColor
}

View File

@ -11,17 +11,17 @@ import Foundation
@objcMembers public class ProgressBarModel: MoleculeModelProtocol {
public static var identifier: String = "progressBar"
@Percent public var percent: CGFloat
public var progressColor: Color = Color(uiColor: .mfCerulean())
public var color: Color = Color(uiColor: .mfCerulean())
public var backgroundColor: Color? = Color(uiColor: .mfLightSilver())
public var isRounded: Bool?
public var roundedCorners: Bool?
public var thickness: CGFloat?
private enum CodingKeys: String, CodingKey {
case moleculeName
case isRounded = "roundRect"
case roundedCorners
case thickness
case percent
case progressColor
case color
case backgroundColor
}
@ -32,13 +32,13 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
percent = try typeContainer.decode(CGFloat.self, forKey: .percent)
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .progressColor) {
progressColor = color
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
self.color = color
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) {
backgroundColor = color
}
isRounded = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRounded)
roundedCorners = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedCorners)
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
}
@ -46,9 +46,9 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(percent, forKey: .percent)
try container.encode(progressColor, forKey: .progressColor)
try container.encode(color, forKey: .color)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(isRounded, forKey: .isRounded)
try container.encodeIfPresent(roundedCorners, forKey: .roundedCorners)
try container.encodeIfPresent(thickness, forKey: .thickness)
}
}

View File

@ -25,13 +25,13 @@ public typealias ActionBlockConfirmation = () -> (Bool)
//--------------------------------------------------
/// Holds the on and off colors for the container.
public var containerTintColor: (on: UIColor?, off: UIColor?)? = (on: .mvmGreen, off: .mvmBlack)
public var containerTintColor: (on: UIColor, off: UIColor) = (on: .mvmGreen, off: .mvmBlack)
/// Holds the on and off colors for the knob.
public var knobTintColor: (on: UIColor?, off: UIColor?)? = (on: .mvmWhite, off: .mvmWhite)
public var knobTintColor: (on: UIColor, off: UIColor) = (on: .mvmWhite, off: .mvmWhite)
/// Holds the on and off colors for the disabled state..
public var disabledTintColor: (container: UIColor?, knob: UIColor?)? = (container: .mvmCoolGray3, knob: .mvmWhite)
public var disabledTintColor: (container: UIColor, knob: UIColor) = (container: .mvmCoolGray3, knob: .mvmWhite)
/// Set this flag to false if you do not want to animate state changes.
public var isAnimated = true
@ -62,8 +62,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
didSet {
isUserInteractionEnabled = isEnabled
changeStateNoAnimation(isEnabled ? isOn : false)
backgroundColor = isEnabled ? containerTintColor?.off : disabledTintColor?.container
knobView.backgroundColor = isEnabled ? knobTintColor?.off : disabledTintColor?.knob
backgroundColor = isEnabled ? (isOn ? containerTintColor.on : containerTintColor.off) : disabledTintColor.container
knobView.backgroundColor = isEnabled ? (isOn ? knobTintColor.on : knobTintColor.off) : disabledTintColor.knob
}
}
@ -80,12 +80,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
if isAnimated {
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
if self.isOn {
self.knobView.backgroundColor = self.knobTintColor?.on
self.backgroundColor = self.containerTintColor?.on
self.knobView.backgroundColor = self.knobTintColor.on
self.backgroundColor = self.containerTintColor.on
} else {
self.knobView.backgroundColor = self.knobTintColor?.off
self.backgroundColor = self.containerTintColor?.off
self.knobView.backgroundColor = self.knobTintColor.off
self.backgroundColor = self.containerTintColor.off
}
}, completion: nil)
@ -96,12 +96,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
}, completion: nil)
} else {
backgroundColor = isOn ? containerTintColor?.on : containerTintColor?.off
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
backgroundColor = isOn ? containerTintColor.on : containerTintColor.off
knobView.backgroundColor = isOn ? knobTintColor.on : knobTintColor.off
self.constrainKnob()
}
(model as? ToggleModel)?.state = isOn
toggleModel?.state = isOn
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
setNeedsLayout()
@ -109,6 +109,10 @@ public typealias ActionBlockConfirmation = () -> (Bool)
}
}
public var toggleModel: ToggleModel? {
return model as? ToggleModel
}
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
@ -189,7 +193,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
public override func setupView() {
super.setupView()
guard subviews.isEmpty else { return }
isAccessibilityElement = true
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
@ -202,7 +206,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
widthConstraint?.isActive = true
layer.cornerRadius = Self.containerSize.height / 2.0
backgroundColor = containerTintColor?.off
backgroundColor = containerTintColor.off
addSubview(knobView)
@ -222,9 +226,9 @@ public typealias ActionBlockConfirmation = () -> (Bool)
public override func reset() {
super.reset()
backgroundColor = containerTintColor?.off
knobView.backgroundColor = knobTintColor?.off
isAnimated = false
backgroundColor = containerTintColor.off
knobView.backgroundColor = knobTintColor.off
isAnimated = true
isOn = false
constrainKnob()
didToggleAction = nil
@ -344,26 +348,14 @@ public typealias ActionBlockConfirmation = () -> (Bool)
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
if let color = model.onTintColor?.uiColor {
containerTintColor?.on = color
}
if let color = model.offTintColor?.uiColor {
containerTintColor?.off = color
}
if let color = model.onKnobTintColor?.uiColor {
knobTintColor?.on = color
}
if let color = model.offKnobTintColor?.uiColor {
knobTintColor?.off = color
}
containerTintColor.on = model.onTintColor.uiColor
containerTintColor.off = model.offTintColor.uiColor
knobTintColor.on = model.onKnobTintColor.uiColor
knobTintColor.off = model.offKnobTintColor.uiColor
changeStateNoAnimation(model.state)
isAnimated = model.animated
isEnabled = model.enabled
if let actionMap = model.action?.toJSON() {
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
}

View File

@ -8,8 +8,12 @@
import UIKit
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "toggle"
public var backgroundColor: Color?
public var state: Bool = false
@ -18,10 +22,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
public var action: ActionModelProtocol?
public var alternateAction: ActionModelProtocol?
public var accessibilityText: String?
public var onTintColor: Color?
public var offTintColor: Color?
public var onKnobTintColor: Color?
public var offKnobTintColor: Color?
public var onTintColor: Color = Color(uiColor: .mvmGreen)
public var offTintColor: Color = Color(uiColor: .mvmBlack)
public var onKnobTintColor: Color = Color(uiColor: .mvmWhite)
public var offKnobTintColor: Color = Color(uiColor: .mvmWhite)
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
@ -75,19 +79,35 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.state = state
}
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
self.animated = animated
}
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor)
offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor)
onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor)
offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor)
if let onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor) {
self.onTintColor = onTintColor
}
if let offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor) {
self.offTintColor = offTintColor
}
if let onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor) {
self.onKnobTintColor = onKnobTintColor
}
if let offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor) {
self.offKnobTintColor = offKnobTintColor
}
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
baseValue = state
@ -106,10 +126,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
try container.encode(state, forKey: .state)
try container.encode(animated, forKey: .animated)
try container.encode(enabled, forKey: .enabled)
try container.encodeIfPresent(onTintColor, forKey: .onTintColor)
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor)
try container.encode(onTintColor, forKey: .onTintColor)
try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
try container.encode(offKnobTintColor, forKey: .offKnobTintColor)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)

View File

@ -1,5 +1,5 @@
//
// GraphView.swift
// Wheel.swift
// MobileFirstFramework
//
// Created by Ryan on 10/24/19.
@ -8,12 +8,12 @@
import UIKit
@objcMembers open class GraphView: View, MVMCoreUIViewConstrainingProtocol {
@objcMembers open class Wheel: View, MVMCoreUIViewConstrainingProtocol {
var heightConstraint: NSLayoutConstraint?
var gradientLayer: CALayer?
var graphModel: CircleProgressModel? {
return model as? CircleProgressModel
var graphModel: WheelModel? {
return model as? WheelModel
}
// MARK: setup
@ -28,7 +28,7 @@ import UIKit
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? CircleProgressModel else { return }
guard let model = model as? WheelModel else { return }
createGraphCircle(model)
rotationAnimation(model)
}
@ -42,7 +42,7 @@ import UIKit
}
// MARK: circle
open func createGraphCircle(_ graphObject: CircleProgressModel) {
open func createGraphCircle(_ graphObject: WheelModel) {
if let sublayers = layer.sublayers {
for sublayer in sublayers {
sublayer.removeAllAnimations()
@ -56,7 +56,7 @@ import UIKit
//begin point will be at the bottom, clockwise direction
let path = UIBezierPath(arcCenter: CGPoint(x: radius
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(GraphView.getPiValue(90.0)), endAngle: CGFloat(GraphView.getPiValue(90.0 + 360.0)), clockwise: true)
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(Wheel.getPiValue(90.0)), endAngle: CGFloat(Wheel.getPiValue(90.0 + 360.0)), clockwise: true)
path.lineWidth = graphObject.lineWidth
let circleLayer = CAShapeLayer()
@ -83,7 +83,7 @@ import UIKit
| | |
-------------
*/
func createGradientLayer(_ graphObject: CircleProgressModel) -> CALayer {
func createGradientLayer(_ graphObject: WheelModel) -> CALayer {
let containLayer = CALayer()
containLayer.frame = CGRect(x: 0, y: 0, width: graphObject.diameter, height: graphObject.diameter)
let radius = graphObject.diameter / 2.0
@ -151,18 +151,18 @@ import UIKit
}
//MARK: Animation
func rotationAnimation(_ object: CircleProgressModel) {
func rotationAnimation(_ object: WheelModel) {
MVMCoreDispatchUtility.performBlock(onMainThread:{
let rotation = CABasicAnimation(keyPath: "transform.rotation")
let animationHandler = GraphViewAnimationHandler.shared
let animationHandler = WheelAnimationHandler.shared
let startAngle = animationHandler.getAnimationStartAngle(object.duration, CACurrentMediaTime())
if startAngle == 0.0 {
animationHandler.storeAnimation(object.duration, CACurrentMediaTime())
}
var fromValue = GraphView.getPiValue(0.0 + startAngle), toValue = GraphView.getPiValue(360.0 + startAngle)
var fromValue = Wheel.getPiValue(0.0 + startAngle), toValue = Wheel.getPiValue(360.0 + startAngle)
if !object.clockwise {
fromValue = GraphView.getPiValue(360.0 - startAngle)
toValue = GraphView.getPiValue(0.0 - startAngle)
fromValue = Wheel.getPiValue(360.0 - startAngle)
toValue = Wheel.getPiValue(0.0 - startAngle)
}
rotation.fromValue = fromValue
rotation.toValue = toValue
@ -180,7 +180,7 @@ import UIKit
}
extension GraphView: CAAnimationDelegate {
extension Wheel: CAAnimationDelegate {
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if let object = graphModel {
rotationAnimation(object)

View File

@ -1,5 +1,5 @@
//
// GraphViewAnimationHandler.swift
// WheelAnimationHandler.swift
// MobileFirstFramework
//
// Created by Ryan on 10/29/19.
@ -8,12 +8,12 @@
import UIKit
@objcMembers open class GraphViewAnimationHandler: NSObject {
@objcMembers open class WheelAnimationHandler: NSObject {
/// duration : CACurrentMediaTime()
private var animations = [Double: Double]()
static let shared = GraphViewAnimationHandler()
static let shared = WheelAnimationHandler()
open func storeAnimation(_ duration: Double, _ currentTime: CFTimeInterval) {
guard animations[duration] == nil else {

View File

@ -1,5 +1,5 @@
//
// CircleProgressModel.swift
// WheelModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 1/13/20.
@ -16,9 +16,9 @@ public enum GraphStyle: String, Codable {
case unlimited, safetyMode
}
public class CircleProgressModel: MoleculeModelProtocol {
public class WheelModel: MoleculeModelProtocol {
public static var identifier: String = "circleProgress"
public static var identifier: String = "wheel"
public var style: GraphStyle = .unlimited {
didSet {
updateStyle()

View File

@ -37,8 +37,7 @@ import Foundation
/// Call to register all of the CoreUI molecules.
public static func registerObjects() {
// Stacks
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: MoleculeStackModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Stack<StackModel>.self, viewModelClass: StackModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: StackModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
@ -79,7 +78,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MFLoadImageView.self, viewModelClass: ImageViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Wheel.self, viewModelClass: WheelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)

View File

@ -71,9 +71,6 @@ import UIKit
}
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
if radioButton.isEnabled {
radioButton.tapAction()
}
radioButton.tapAction()
}
}

View File

@ -8,7 +8,7 @@
import Foundation
@objcMembers open class ListRVWheel: TableViewCell {
let wheel = GraphView(frame: .zero)
let wheel = Wheel(frame: .zero)
let leftLabel = Label.commonLabelB1(true)
let rightLabel = Label.commonLabelB2(true)
var stack: Stack<StackModel>

View File

@ -11,9 +11,9 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "listRVWheel"
public var leftLabel: LabelModel
public var rightLabel: LabelModel
public var wheel : CircleProgressModel
public var wheel: WheelModel
public init(leftLabel: LabelModel, rightLabel: LabelModel, wheel: CircleProgressModel) {
public init(leftLabel: LabelModel, rightLabel: LabelModel, wheel: WheelModel) {
self.leftLabel = leftLabel
self.rightLabel = rightLabel
self.wheel = wheel
@ -37,7 +37,7 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
wheel = try typeContainer.decodeIfPresent(CircleProgressModel.self, forKey: .wheel) ?? CircleProgressModel()
wheel = try typeContainer.decodeIfPresent(WheelModel.self, forKey: .wheel) ?? WheelModel()
try super.init(from: decoder)
}

View File

@ -86,7 +86,7 @@ import Foundation
for item in model.sections {
stackItems.append(MoleculeStackItemModel(with: item))
}
let stack = MoleculeStackModel(molecules: stackItems)
let stack = StackModel(molecules: stackItems)
stack.verticalAlignment = .fill
colorLablesStack.set(with: stack, delegateObject, additionalData)
}

View File

@ -8,7 +8,7 @@
import Foundation
public protocol StackItemModelProtocol: MoleculeModelProtocol {
public protocol StackItemModelProtocol {
var spacing: CGFloat? { get set }
var percent: Int? { get set }
var gone: Bool { get set }

View File

@ -164,10 +164,12 @@ import UIKit
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? CornerLabelsModel else { return }
if middleView != nil {
(middleView as? MoleculeViewProtocol)?.set(with: model, delegateObject, additionalData)
} else if let moleculeModel = model.molecule, let molecule = MoleculeObjectMapping.shared()?.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
addMiddleView(molecule)
if let moleculeModel = model.molecule {
if middleView != nil {
(middleView as? MoleculeViewProtocol)?.set(with: moleculeModel, delegateObject, additionalData)
} else if let molecule = MoleculeObjectMapping.shared()?.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
addMiddleView(molecule)
}
}
topLeftLabel.setOptional(with: model.topLeftLabel, delegateObject, additionalData)

View File

@ -8,7 +8,7 @@
import Foundation
@objcMembers public class NumberedListModel: MoleculeStackModel {
@objcMembers public class NumberedListModel: StackModel {
public override class var identifier: String {
return "numberedList"
}
@ -28,8 +28,7 @@ import Foundation
for (index, molecule) in list.enumerated() {
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: "\(index+1).", molecule: molecule)))
}
super.init(molecules: models)
spacing = 0
super.init(molecules: models, spacing: 0)
}
public override func encode(to encoder: Encoder) throws {
@ -39,7 +38,7 @@ import Foundation
var models: [MoleculeModelProtocol] = []
for molecule in molecules {
models.append(molecule.molecule)
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
}
try container.encodeModels(models, forKey: .list)
}

View File

@ -11,8 +11,9 @@ import UIKit
// This class is only temporarily necessary. Eventually we will have initWithModel instad of just init for moleculeviews, which will remove this need.
open class StringAndMoleculeStack: MoleculeStackView {
override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
guard let model = stackModel else { return }
for stackItemModel in model.molecules {
guard let model = model as? StackModelProtocol,
let molcules = model.molecules as? [MoleculeStackItemModel] else { return }
for stackItemModel in molcules {
guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(stringAndMoleculeModel.molecule, delegateObject: delegateObject
, additionalData: additionalData) else {

View File

@ -10,7 +10,6 @@ import Foundation
open class StringAndMoleculeView: View {
var label = Label.commonLabelB2(true)
var string: String
var molecule: MoleculeViewProtocol
var leftWidthConstraint: NSLayoutConstraint?
@ -28,7 +27,7 @@ open class StringAndMoleculeView: View {
// MARK: - Inits
public init(string: String, molecule: MoleculeViewProtocol) {
self.string = string
self.label.text = string
self.molecule = molecule
super.init(frame: .zero)
}

View File

@ -8,7 +8,7 @@
import Foundation
@objcMembers public class UnOrderedListModel: MoleculeStackModel {
@objcMembers public class UnOrderedListModel: StackModel {
public override class var identifier: String {
return "unOrderedList"
}
@ -33,8 +33,7 @@ import Foundation
for molecule in list {
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: bulletChar, molecule: molecule)))
}
super.init(molecules: models)
spacing = 0
super.init(molecules: models, spacing: 0)
}
public override func encode(to encoder: Encoder) throws {
@ -45,7 +44,7 @@ import Foundation
var models: [MoleculeModelProtocol] = []
for molecule in molecules {
models.append(molecule.molecule)
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
}
try container.encodeModels(models, forKey: .list)
}

View File

@ -1,54 +0,0 @@
//
// MoleculeStack.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 10/3/19.
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
//
// A stack that has a list molecule stack items.
import Foundation
@objcMembers public class MoleculeStackModel: ContainerModel, MoleculeModelProtocol, StackModelProtocol {
public class var identifier: String {
return "stack"
}
public var backgroundColor: Color?
public var molecules: [MoleculeStackItemModel]
public var axis: NSLayoutConstraint.Axis = .vertical
public var spacing: CGFloat = 16.0
public var useStackSpacingBeforeFirstItem = false
public init(molecules: [MoleculeStackItemModel]) {
self.molecules = molecules
super.init()
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case molecules
case axis
case spacing
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecules = try typeContainer.decode([MoleculeStackItemModel].self, forKey: .molecules)
if let axisString = try typeContainer.decodeIfPresent(String.self, forKey: .axis), let optionalAxis = NSLayoutConstraint.Axis(rawValue: axisString) {
axis = optionalAxis
}
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
self.spacing = spacing
}
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(molecules, forKey: .molecules)
try container.encodeIfPresent(axis.rawValueString, forKey: .axis)
try container.encodeIfPresent(spacing, forKey: .spacing)
}
}

View File

@ -5,13 +5,12 @@
// Created by Scott Pfeil on 2/11/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
// This is a dynamic stack view that creates molecules if needed on set.
import UIKit
open class MoleculeStackView: Stack<MoleculeStackModel> {
open override var stackModel: MoleculeStackModel? {
get { return model as? MoleculeStackModel }
}
open class MoleculeStackView: Stack<StackModel> {
var previousModel: MoleculeModelProtocol?
/// Convenience function, adds a molecule to a MoleculeStackItem to the MoleculeStack
func setup(with views: [View], lastItem: Bool) {
@ -26,14 +25,16 @@ open class MoleculeStackView: Stack<MoleculeStackModel> {
if let stackModel = stackModel {
stackModel.molecules = models
} else {
model = MoleculeStackModel(molecules: models)
model = StackModel(molecules: models)
}
restack()
}
// MARK: - Adding to stack
/// Creates all of the stackItems for the stackItemModels
override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
/// Can be subclassed to create views when we get stack item models and have no views yet
open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
guard let stackItemModels = stackModel?.molecules else { return }
for model in stackItemModels {
if let stackItem = MoleculeObjectMapping.shared()?.createMolecule(model, delegateObject: delegateObject, additionalData: additionalData) as? MoleculeStackItem {
@ -41,4 +42,20 @@ open class MoleculeStackView: Stack<MoleculeStackModel> {
}
}
}
open override func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
// If the items in the stack are different, clear them, create new ones.
if (previousModel == nil) || Self.nameForReuse(with: previousModel!, delegateObject) != Self.nameForReuse(with: model, delegateObject) {
removeAllItemViews()
stackItems = []
createStackItemsFromModel(model, delegateObject, additionalData)
} else {
super.setStackItemsFromModel(model, delegateObject, additionalData)
}
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
previousModel = self.model
super.set(with: model, delegateObject, additionalData)
}
}

View File

@ -147,18 +147,8 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
let previousModel = self.model
super.set(with: model, delegateObject, additionalData)
removeAllItemViews()
// If the items in the stack are different, clear them, create new ones.
if (previousModel == nil) || Self.nameForReuse(with: previousModel!, delegateObject) != Self.nameForReuse(with: model, delegateObject) {
stackItems = []
createStackItemsFromModel(model, delegateObject, additionalData)
} else {
setStackItemsFromModel(model, delegateObject, additionalData)
}
setStackItemsFromModel(model, delegateObject, additionalData)
restack()
}
@ -216,9 +206,6 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
// MARK: - Subclassables
//--------------------------------------------------
/// Can be subclassed to create views when we get stack item models and have no views yet
open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { }
/// Can be subclassed to set stack items with model when we already have views
open func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let models = stackModel?.molecules else { return }
@ -243,10 +230,10 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
}
/// Sets the stack with StackItems containing the passed in views and sets the StackModel with models.
open func set(with viewModels:[(view: UIView, model: T.AnyStackItemModel)]) {
open func set(with viewModels:[(view: UIView, model: StackItemModel)]) {
guard var stackModel = self.stackModel else { return }
var stackItems: [StackItem] = []
var models: [T.AnyStackItemModel] = []
var models: [StackItemModel] = []
for item in viewModels {
stackItems.append(StackItem(andContain: item.view))
models.append(item.model)
@ -307,7 +294,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
if let percent = model.percent {
let multiplier = CGFloat(percent) / 100.0
let constant = multiplier * totalSpacing
view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
view.heightAnchor.constraint(equalTo: heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
}
if lastItem {
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
@ -326,7 +313,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
if let percent = model.percent {
let multiplier = CGFloat(percent) / 100.0
let constant = multiplier * totalSpacing
view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
}
if lastItem {
pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)

View File

@ -8,17 +8,19 @@
import Foundation
@objcMembers public class StackModel: StackModelProtocol, MoleculeModelProtocol {
@objcMembers public class StackModel: ContainerModel, StackModelProtocol, MoleculeModelProtocol {
static let defaultSpacing: CGFloat = 16.0
public static var identifier: String = "simpleStack"
public class var identifier: String {
return "stack"
}
public var backgroundColor: Color?
public var molecules: [StackItemModel]
public var molecules: [StackItemModelProtocol & MoleculeModelProtocol]
public var axis: NSLayoutConstraint.Axis = .vertical
public var spacing: CGFloat = StackModel.defaultSpacing
public var useStackSpacingBeforeFirstItem = false
public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) {
public init(molecules: [StackItemModelProtocol & MoleculeModelProtocol], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) {
self.molecules = molecules
if let axis = axis {
self.axis = axis
@ -26,6 +28,7 @@ import Foundation
if let spacing = spacing {
self.spacing = spacing
}
super.init()
}
private enum CodingKeys: String, CodingKey {
@ -38,19 +41,20 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecules = try typeContainer.decode([StackItemModel].self, forKey: .molecules)
molecules = try typeContainer.decodeModels(codingKey: .molecules)
if let axisString = try typeContainer.decodeIfPresent(String.self, forKey: .axis), let optionalAxis = NSLayoutConstraint.Axis(rawValue: axisString) {
axis = optionalAxis
}
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
self.spacing = spacing
}
try super.init(from: decoder)
}
public func encode(to encoder: Encoder) throws {
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(molecules, forKey: .molecules)
try container.encodeModels(molecules, forKey: .molecules)
try container.encodeIfPresent(axis.rawValueString, forKey: .axis)
try container.encodeIfPresent(spacing, forKey: .spacing)
try container.encode(moleculeName, forKey: .moleculeName)

View File

@ -9,9 +9,7 @@
import Foundation
public protocol StackModelProtocol {
associatedtype AnyStackItemModel: StackItemModelProtocol
var molecules: [AnyStackItemModel] { get set }
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
var axis: NSLayoutConstraint.Axis { get set }
var spacing: CGFloat { get set }
var useStackSpacingBeforeFirstItem: Bool { get set }

View File

@ -15,10 +15,10 @@ import Foundation
}
public var header: MoleculeModelProtocol?
public var moleculeStack: MoleculeStackModel
public var moleculeStack: StackModel
public var footer: MoleculeModelProtocol?
public init(pageType: String, moleculeStack: MoleculeStackModel) {
public init(pageType: String, moleculeStack: StackModel) {
self.moleculeStack = moleculeStack
super.init(pageType: pageType)
}
@ -31,7 +31,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .stack)
moleculeStack = try typeContainer.decode(StackModel.self, forKey: .stack)
header = try typeContainer.decodeModelIfPresent(codingKey: .header)
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
try super.init(from: decoder)

View File

@ -236,10 +236,13 @@ import UIKit
}
// MARK: - View lifecycle
/// Called only once in viewDidLoad
open func initialLoad() {
observeForResponseJSONUpdates()
}
/// Called on screen size update.
open func updateViews() {
_ = formValidator?.validate()
}
@ -265,8 +268,7 @@ import UIKit
initialLoad()
}
// Handle data for first load. Dispatched to allow subclasses to finish their view did load implementations.
self.handleNewDataAndUpdateUI()
handleNewDataAndUpdateUI()
}
open override func viewDidLayoutSubviews() {

View File

@ -198,7 +198,7 @@
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=space-[button]->=space-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(PaddingFive)} views:NSDictionaryOfVariableBindings(button)]];
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:PaddingThree].active = YES;
[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)].active = YES;
[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)].active = YES;
self.button = button;
}
} else {
@ -210,7 +210,7 @@
}
if (!self.labelRightConstraint) {
self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)];
self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)];
}
self.labelRightConstraint.active = YES;
}