Merge branch 'develop' into feature/new_loading_spinner
This commit is contained in:
commit
5127a69636
@ -82,6 +82,7 @@
|
||||
0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; };
|
||||
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; };
|
||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
|
||||
0A6C1FC324927E2E00E64B52 /* colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A6C1FC224927E2E00E64B52 /* colors.xcassets */; };
|
||||
0A775F2624893916009EFB58 /* ThreeHeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */; };
|
||||
0A775F2824893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */; };
|
||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||
@ -213,6 +214,8 @@
|
||||
AA633B3324989ED500731E80 /* HeadersH2PricingTwoRows.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */; };
|
||||
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */; };
|
||||
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */; };
|
||||
AA71AD3E24A32FCE00ACA76F /* HeadersH2LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */; };
|
||||
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */; };
|
||||
AA7F32AB246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */; };
|
||||
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */; };
|
||||
AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; };
|
||||
@ -225,6 +228,8 @@
|
||||
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; };
|
||||
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; };
|
||||
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; };
|
||||
AAE7270C24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */; };
|
||||
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */; };
|
||||
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; };
|
||||
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
|
||||
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
|
||||
@ -292,6 +297,8 @@
|
||||
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; };
|
||||
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* TemplateModel.swift */; };
|
||||
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
|
||||
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; };
|
||||
D2351C7C24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */; };
|
||||
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; };
|
||||
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
|
||||
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; };
|
||||
@ -534,6 +541,7 @@
|
||||
0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
|
||||
0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = "<group>"; };
|
||||
0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||
0A6C1FC224927E2E00E64B52 /* colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = colors.xcassets; path = MVMCoreUI/Categories/colors.xcassets; sourceTree = SOURCE_ROOT; };
|
||||
0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLink.swift; sourceTree = "<group>"; };
|
||||
0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLinkModel.swift; sourceTree = "<group>"; };
|
||||
0A7918F423F5E7EA00772FF4 /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
|
||||
@ -669,6 +677,8 @@
|
||||
AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2PricingTwoRows.swift; sourceTree = "<group>"; };
|
||||
AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyText.swift; sourceTree = "<group>"; };
|
||||
AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyTextModel.swift; sourceTree = "<group>"; };
|
||||
AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2LinkModel.swift; sourceTree = "<group>"; };
|
||||
AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Link.swift; sourceTree = "<group>"; };
|
||||
AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||
AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||
AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -681,6 +691,8 @@
|
||||
AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = "<group>"; };
|
||||
AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; };
|
||||
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = "<group>"; };
|
||||
AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLinkModel.swift; sourceTree = "<group>"; };
|
||||
AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLink.swift; sourceTree = "<group>"; };
|
||||
BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = "<group>"; };
|
||||
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
|
||||
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
|
||||
@ -748,6 +760,8 @@
|
||||
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D22D8392241C27B100D3DF69 /* TemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModel.swift; sourceTree = "<group>"; };
|
||||
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
|
||||
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||
D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||
D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = "<group>"; };
|
||||
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; };
|
||||
D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1156,6 +1170,8 @@
|
||||
8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */,
|
||||
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */,
|
||||
C7F8012023E8303200396FBD /* ListRVWheel.swift */,
|
||||
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */,
|
||||
D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */,
|
||||
);
|
||||
path = RightVariable;
|
||||
sourceTree = "<group>";
|
||||
@ -1506,7 +1522,7 @@
|
||||
children = (
|
||||
AA104AC824472DC7004D2810 /* HeadersH1ButtonModel.swift */,
|
||||
AA104AC624472DB0004D2810 /* HeadersH1Button.swift */,
|
||||
AA104ADB244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift */,
|
||||
AA104ADB244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift */,
|
||||
AA104AD9244734DB004D2810 /* HeadersH1LandingPageHeader.swift */,
|
||||
);
|
||||
path = H1;
|
||||
@ -1521,8 +1537,12 @@
|
||||
AA26850B244840AE00CE34CC /* HeadersH2TinyButton.swift */,
|
||||
AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */,
|
||||
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */,
|
||||
AA633B3024989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift */,
|
||||
AA633B3024989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift */,
|
||||
AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */,
|
||||
AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */,
|
||||
AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */,
|
||||
AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */,
|
||||
AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */,
|
||||
);
|
||||
path = H2;
|
||||
sourceTree = "<group>";
|
||||
@ -1867,6 +1887,7 @@
|
||||
D29DF26621E6A9E4003B2FB9 /* ThirdParty */,
|
||||
D29DF31521ECECC0003B2FB9 /* Fonts */,
|
||||
D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */,
|
||||
0A6C1FC224927E2E00E64B52 /* colors.xcassets */,
|
||||
);
|
||||
path = SupportingFiles;
|
||||
sourceTree = "<group>";
|
||||
@ -2085,6 +2106,7 @@
|
||||
files = (
|
||||
94CA227C24058534002D6750 /* VerizonNHGeTX-Bold.otf in Resources */,
|
||||
D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */,
|
||||
0A6C1FC324927E2E00E64B52 /* colors.xcassets in Resources */,
|
||||
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */,
|
||||
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */,
|
||||
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */,
|
||||
@ -2149,6 +2171,7 @@
|
||||
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
|
||||
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */,
|
||||
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */,
|
||||
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */,
|
||||
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
||||
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
|
||||
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */,
|
||||
@ -2316,6 +2339,7 @@
|
||||
BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */,
|
||||
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */,
|
||||
D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */,
|
||||
D2351C7C24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift in Sources */,
|
||||
017BEB7B236763000024EF95 /* LineModel.swift in Sources */,
|
||||
D256E9932412880000360572 /* Header.swift in Sources */,
|
||||
94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */,
|
||||
@ -2361,6 +2385,7 @@
|
||||
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */,
|
||||
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */,
|
||||
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */,
|
||||
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */,
|
||||
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
|
||||
324FB6AC24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift in Sources */,
|
||||
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */,
|
||||
@ -2405,6 +2430,7 @@
|
||||
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */,
|
||||
D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */,
|
||||
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
|
||||
AA71AD3E24A32FCE00ACA76F /* HeadersH2LinkModel.swift in Sources */,
|
||||
8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */,
|
||||
D243859923A16B1800332775 /* Container.swift in Sources */,
|
||||
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */,
|
||||
@ -2414,6 +2440,7 @@
|
||||
AA26850E244840C300CE34CC /* HeadersH2TinyButtonModel.swift in Sources */,
|
||||
D260105F23D0BFFC00764D80 /* StackItem.swift in Sources */,
|
||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */,
|
||||
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */,
|
||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */,
|
||||
8DE5BECF2456F7B100772E76 /* ListTwoColumnDropdownSelectors.swift in Sources */,
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||
@ -2462,6 +2489,7 @@
|
||||
D264FA90243BCE6800D98315 /* ThreeLayerCollectionViewController.swift in Sources */,
|
||||
AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */,
|
||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
|
||||
AAE7270C24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift in Sources */,
|
||||
BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */,
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
|
||||
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */,
|
||||
|
||||
@ -25,12 +25,9 @@ import UIKit
|
||||
if numberOfDigits > 0 {
|
||||
var digitBoxes = [DigitBox]()
|
||||
|
||||
let ordinalFormatter = NumberFormatter()
|
||||
ordinalFormatter.numberStyle = .ordinal
|
||||
|
||||
for i in 0..<numberOfDigits {
|
||||
let newDigitBox = createDigitField()
|
||||
let accessibileLabel = ordinalFormatter.string(from: NSNumber(value: i + 1)) ?? ""
|
||||
let accessibileLabel = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: i + 1)) ?? ""
|
||||
newDigitBox.digitField.accessibilityLabel = "\(accessibileLabel) field of \(numberOfDigits) digit fields"
|
||||
digitBoxes.append(newDigitBox)
|
||||
}
|
||||
|
||||
@ -26,6 +26,18 @@ open class RadioBox: Control {
|
||||
return model as? RadioBoxModel
|
||||
}
|
||||
|
||||
public override var isSelected: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
@ -56,6 +68,8 @@ open class RadioBox: Control {
|
||||
subTextLabelHeightConstraint?.isActive = true
|
||||
|
||||
addTarget(self, action: #selector(selectBox), for: .touchUpInside)
|
||||
|
||||
isAccessibilityElement = true
|
||||
}
|
||||
|
||||
// MARK: - MoleculeViewProtocol
|
||||
@ -63,8 +77,6 @@ open class RadioBox: Control {
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? RadioBoxModel else { return }
|
||||
isSelected = model.selected
|
||||
isEnabled = model.enabled
|
||||
label.text = model.text
|
||||
subTextLabel.text = model.subText
|
||||
isOutOfStock = model.strikethrough
|
||||
@ -72,6 +84,8 @@ open class RadioBox: Control {
|
||||
if let color = model.selectedAccentColor?.uiColor {
|
||||
accentColor = color
|
||||
}
|
||||
isSelected = model.selected
|
||||
isEnabled = model.enabled
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
@ -91,7 +105,6 @@ open class RadioBox: Control {
|
||||
strikeLayer = line
|
||||
}
|
||||
|
||||
|
||||
// Draw the border
|
||||
borderLayer?.removeFromSuperlayer()
|
||||
if isSelected {
|
||||
@ -191,5 +204,25 @@ open class RadioBox: Control {
|
||||
mask.frame = bounds
|
||||
return mask
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
public func updateAccessibility() {
|
||||
var message = ""
|
||||
if let labelText = label.text, label.hasText {
|
||||
message += labelText + ", "
|
||||
}
|
||||
if let subLabelText = subTextLabel.text, subTextLabel.hasText {
|
||||
message += subLabelText + ", "
|
||||
}
|
||||
accessibilityLabel = message
|
||||
|
||||
accessibilityTraits = .button
|
||||
if isSelected {
|
||||
accessibilityTraits.insert(.selected)
|
||||
}
|
||||
if !isEnabled {
|
||||
accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ open class RadioBoxCollectionViewCell: CollectionViewCell {
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
isAccessibilityElement = true
|
||||
addMolecule(radioBox)
|
||||
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||
}
|
||||
@ -24,5 +25,12 @@ open class RadioBoxCollectionViewCell: CollectionViewCell {
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? RadioBoxModel else { return }
|
||||
radioBox.set(with: model, delegateObject, additionalData)
|
||||
updateAccessibility()
|
||||
}
|
||||
|
||||
open func updateAccessibility() {
|
||||
accessibilityLabel = radioBox.accessibilityLabel
|
||||
accessibilityHint = radioBox.accessibilityHint
|
||||
accessibilityTraits = radioBox.accessibilityTraits
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,13 @@ open class RadioBoxes: View {
|
||||
}
|
||||
}
|
||||
|
||||
open func updateAccessibilityValue(collectionView: UICollectionView, cell: RadioBoxCollectionViewCell, indexPath: IndexPath) {
|
||||
guard let format = MVMCoreUIUtility.hardcodedString(withKey: "index_string_of_total"),
|
||||
let indexString = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: indexPath.row + 1)) else { return }
|
||||
let total = self.collectionView(collectionView, numberOfItemsInSection: indexPath.section)
|
||||
cell.accessibilityValue = String(format: format, indexString, total)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
@ -136,6 +143,7 @@ extension RadioBoxes: UICollectionViewDataSource {
|
||||
if molecule.selected {
|
||||
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
|
||||
}
|
||||
updateAccessibilityValue(collectionView: collectionView, cell: cell, indexPath: indexPath)
|
||||
cell.layoutIfNeeded()
|
||||
return cell
|
||||
}
|
||||
@ -151,11 +159,13 @@ extension RadioBoxes: UICollectionViewDelegate {
|
||||
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||
cell.radioBox.selectBox()
|
||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||
cell.updateAccessibility()
|
||||
}
|
||||
|
||||
open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
||||
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||
cell.radioBox.deselectBox()
|
||||
cell.updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,18 @@ open class RadioSwatch: Control {
|
||||
return model as? RadioSwatchModel
|
||||
}
|
||||
|
||||
public override var isSelected: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
@ -45,9 +57,9 @@ open class RadioSwatch: Control {
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? RadioSwatchModel else { return }
|
||||
bottomText.text = model.text
|
||||
isSelected = model.selected
|
||||
isEnabled = model.enabled
|
||||
bottomText.text = model.text
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
@ -163,4 +175,17 @@ open class RadioSwatch: Control {
|
||||
mask.frame = bounds
|
||||
return mask
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
public func updateAccessibility() {
|
||||
accessibilityLabel = bottomText.accessibilityLabel ?? bottomText.text
|
||||
|
||||
accessibilityTraits = .button
|
||||
if isSelected {
|
||||
accessibilityTraits.insert(.selected)
|
||||
}
|
||||
if !isEnabled {
|
||||
accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ open class RadioSwatchCollectionViewCell: CollectionViewCell {
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
isAccessibilityElement = true
|
||||
addMolecule(radioSwatch)
|
||||
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||
}
|
||||
@ -19,5 +20,24 @@ open class RadioSwatchCollectionViewCell: CollectionViewCell {
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? RadioSwatchModel else { return }
|
||||
radioSwatch.set(with: model, delegateObject, additionalData)
|
||||
updateAccessibility()
|
||||
}
|
||||
|
||||
open func updateAccessibility() {
|
||||
accessibilityLabel = radioSwatch.accessibilityLabel
|
||||
accessibilityHint = radioSwatch.accessibilityHint
|
||||
accessibilityTraits = radioSwatch.accessibilityTraits
|
||||
}
|
||||
|
||||
open override func accessibilityElementDidBecomeFocused() {
|
||||
super.accessibilityElementDidBecomeFocused()
|
||||
radioSwatch.bottomText.isHidden = false
|
||||
}
|
||||
|
||||
open override func accessibilityElementDidLoseFocus() {
|
||||
super.accessibilityElementDidLoseFocus()
|
||||
if !radioSwatch.isSelected {
|
||||
radioSwatch.bottomText.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +101,13 @@ open class RadioSwatches: View {
|
||||
}
|
||||
collectionViewHeight?.constant = CGFloat(height)
|
||||
}
|
||||
|
||||
open func updateAccessibilityValue(collectionView: UICollectionView, cell: RadioSwatchCollectionViewCell, indexPath: IndexPath) {
|
||||
guard let format = MVMCoreUIUtility.hardcodedString(withKey: "index_string_of_total"),
|
||||
let indexString = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: indexPath.row + 1)) else { return }
|
||||
let total = self.collectionView(collectionView, numberOfItemsInSection: indexPath.section)
|
||||
cell.accessibilityValue = String(format: format, indexString, total)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
@ -128,6 +135,7 @@ extension RadioSwatches: UICollectionViewDataSource {
|
||||
if molecule.selected {
|
||||
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
|
||||
}
|
||||
updateAccessibilityValue(collectionView: collectionView, cell: cell, indexPath: indexPath)
|
||||
cell.layoutIfNeeded()
|
||||
return cell
|
||||
}
|
||||
@ -143,10 +151,12 @@ extension RadioSwatches: UICollectionViewDelegate {
|
||||
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
|
||||
cell.radioSwatch.selectSwatch()
|
||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||
cell.updateAccessibility()
|
||||
}
|
||||
|
||||
open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
||||
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
|
||||
cell.radioSwatch.deselectSwatch()
|
||||
cell.updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,13 +110,10 @@ open class BarsIndicatorView: CarouselIndicator {
|
||||
|
||||
var bars = [(View, NSLayoutConstraint)]()
|
||||
|
||||
let ordinalFormatter = NumberFormatter()
|
||||
ordinalFormatter.numberStyle = .ordinal
|
||||
|
||||
for i in 0..<numberOfPages {
|
||||
let bar = View()
|
||||
bar.isAccessibilityElement = true
|
||||
if let accessibleValueFormat = accessibilityValueFormat, let accessibleIndex = ordinalFormatter.string(from: NSNumber(value: i + 1)) {
|
||||
if let accessibleValueFormat = accessibilityValueFormat, let accessibleIndex = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: i + 1)) {
|
||||
bar.accessibilityLabel = String(format: accessibleValueFormat, accessibleIndex, numberOfPages)
|
||||
}
|
||||
bar.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
|
||||
|
||||
@ -225,11 +225,8 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
|
||||
|
||||
func formatAccessibilityValue(index: Int, total: Int) {
|
||||
|
||||
let ordinalFormatter = NumberFormatter()
|
||||
ordinalFormatter.numberStyle = .ordinal
|
||||
|
||||
guard let accessibleFormat = accessibilityValueFormat,
|
||||
let accessibleIndex = ordinalFormatter.string(from: NSNumber(value: index))
|
||||
let accessibleIndex = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: index))
|
||||
else { return }
|
||||
|
||||
accessibilityValue = String(format: accessibleFormat, accessibleIndex, total)
|
||||
|
||||
@ -63,7 +63,7 @@ import UIKit
|
||||
addSubview(stack)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||
stack.backgroundColor = backgroundColor
|
||||
stack.contentView.backgroundColor = .mvmWhite
|
||||
stack.contentView.backgroundColor = .clear
|
||||
stack.model = StackModel(molecules: [], axis: .horizontal, spacing: 2)
|
||||
stack.stackModel?.horizontalAlignment = .leading
|
||||
|
||||
@ -111,7 +111,6 @@ import UIKit
|
||||
|
||||
roundedCorners = multiProgressModel.roundedCorners ?? false
|
||||
thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight
|
||||
stack.model?.backgroundColor = model.backgroundColor
|
||||
set(with: multiProgressModel.progressList, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
|
||||
@ -44,8 +44,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
}()
|
||||
|
||||
// Sizes are from InVision design specs.
|
||||
static let containerSize = CGSize(width: 46, height: 24)
|
||||
static let knobSize = CGSize(width: 22, height: 22)
|
||||
static let containerSize = CGSize(width: 51, height: 31)
|
||||
static let knobSize = CGSize(width: 28, height: 28)
|
||||
|
||||
private var knobView: View = {
|
||||
let view = View()
|
||||
@ -62,8 +62,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
didSet {
|
||||
isUserInteractionEnabled = isEnabled
|
||||
changeStateNoAnimation(isEnabled ? isOn : false)
|
||||
backgroundColor = isEnabled ? (isOn ? containerTintColor.on : containerTintColor.off) : disabledTintColor.container
|
||||
knobView.backgroundColor = isEnabled ? (isOn ? knobTintColor.on : knobTintColor.off) : disabledTintColor.knob
|
||||
setToggleAppearanceFromState()
|
||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: isEnabled ? "AccToggleHint" : "AccDisabled")
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,8 +96,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
}, completion: nil)
|
||||
|
||||
} else {
|
||||
backgroundColor = isOn ? containerTintColor.on : containerTintColor.off
|
||||
knobView.backgroundColor = isOn ? knobTintColor.on : knobTintColor.off
|
||||
setToggleAppearanceFromState()
|
||||
self.constrainKnob()
|
||||
}
|
||||
|
||||
@ -143,14 +142,14 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
private func constrainKnobOn() {
|
||||
|
||||
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
||||
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 2)
|
||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor)
|
||||
}
|
||||
|
||||
private func constrainKnobOff() {
|
||||
|
||||
knobTrailingConstraint = trailingAnchor.constraint(greaterThanOrEqualTo: knobView.trailingAnchor)
|
||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 2)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -159,7 +158,6 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
public convenience override init() {
|
||||
@ -225,7 +223,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
widthConstraint = widthAnchor.constraint(equalToConstant: Self.containerSize.width)
|
||||
widthConstraint?.isActive = true
|
||||
|
||||
layer.cornerRadius = Self.containerSize.height / 2.0
|
||||
layer.cornerRadius = Self.getContainerHeight() / 2.0
|
||||
backgroundColor = containerTintColor.off
|
||||
|
||||
addSubview(knobView)
|
||||
@ -305,6 +303,16 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
isAnimated = isAnimatedState
|
||||
}
|
||||
|
||||
override open func accessibilityActivate() -> Bool {
|
||||
// Hold state in case User wanted isAnimated to remain off.
|
||||
guard isUserInteractionEnabled else { return false }
|
||||
let isAnimatedState = isAnimated
|
||||
isAnimated = false
|
||||
sendActions(for: .touchUpInside)
|
||||
isAnimated = isAnimatedState
|
||||
return true
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - UIResponder
|
||||
//--------------------------------------------------
|
||||
@ -342,6 +350,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
// MARK: - Animations
|
||||
//--------------------------------------------------
|
||||
|
||||
public func setToggleAppearanceFromState() {
|
||||
|
||||
backgroundColor = isEnabled ? isOn ? containerTintColor.on : containerTintColor.off : disabledTintColor.container
|
||||
knobView.backgroundColor = isEnabled ? isOn ? knobTintColor.on : knobTintColor.off : disabledTintColor.knob
|
||||
}
|
||||
|
||||
public func knobReformAnimation() {
|
||||
|
||||
if isAnimated {
|
||||
@ -378,8 +392,23 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
accessibilityLabel = accessibileString
|
||||
}
|
||||
|
||||
if let actionMap = model.action?.toJSON() {
|
||||
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
||||
let actionMap = model.action?.toJSON()
|
||||
let alternateActionMap = model.alternateAction?.toJSON()
|
||||
if actionMap != nil || alternateActionMap != nil {
|
||||
didToggleAction = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if self.isOn {
|
||||
if actionMap != nil {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
} else {
|
||||
if alternateActionMap != nil {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: alternateActionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
} else if actionMap != nil {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ import Foundation
|
||||
url = try typeContainer.decodeIfPresent(URL.self, forKey: .url)
|
||||
htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString)
|
||||
if url == nil, htmlString == nil {
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped()
|
||||
}
|
||||
height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height)
|
||||
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
|
||||
|
||||
@ -38,7 +38,7 @@ import Foundation
|
||||
public func getMoleculeModelForJSON(_ json: [String: Any]) throws -> MoleculeModelProtocol? {
|
||||
guard let moleculeName = json.optionalStringForKey(KeyMoleculeName),
|
||||
let type = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else {
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped()
|
||||
}
|
||||
guard let model = try type.decode(jsonDict: json) as? MoleculeModelProtocol else {
|
||||
throw ModelRegistry.Error.decoderError
|
||||
@ -181,6 +181,7 @@ import Foundation
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableToggleAllTextAndLinks.self, viewModelClass: ListRightVariableToggleAllTextAndLinksModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
|
||||
@ -211,6 +212,8 @@ import Foundation
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2TinyButton.self, viewModelClass: HeadersH2TinyButtonModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2PricingTwoRows.self, viewModelClass: HeadersH2PricingTwoRowsModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Link.self, viewModelClass: HeadersH2LinkModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2CaretLink.self, viewModelClass: HeadersH2CaretLinkModel.self)
|
||||
|
||||
// MARK:- Device Items
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
|
||||
|
||||
@ -33,9 +33,13 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
topPadding = PaddingDefaultVerticalSpacing3
|
||||
bottomPadding = PaddingDefaultVerticalSpacing3
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
//
|
||||
// HeadersH2CaretLink.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 01/07/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@objcMembers open class HeadersH2CaretLink: HeaderView {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let caretLink = CaretLink()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, caretLink])
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//-------------------------------------------------------
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
headlineBody.stylePageHeader()
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//------------------------------------------------------
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? HeadersH2CaretLinkModel else { return }
|
||||
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||
caretLink.set(with: model.caretLink, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 121
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
headlineBody.stylePageHeader()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
//
|
||||
// HeadersH2CaretLinkModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 01/07/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
public static var identifier: String = "headerH2CrtBtn"
|
||||
public var headlineBody: HeadlineBodyModel
|
||||
public var caretLink: CaretLinkModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
public init(headlineBody: HeadlineBodyModel, caretLink: CaretLinkModel) {
|
||||
self.headlineBody = headlineBody
|
||||
self.caretLink = caretLink
|
||||
super.init()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case headlineBody
|
||||
case caretLink
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||
caretLink = try typeContainer.decode(CaretLinkModel.self, forKey: .caretLink)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(headlineBody, forKey: .headlineBody)
|
||||
try container.encode(caretLink, forKey: .caretLink)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
//
|
||||
// HeadersH2Link.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 24/06/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class HeadersH2Link: HeaderView {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
public let headlineBody = HeadlineBody()
|
||||
public let link = Link()
|
||||
public let stack: Stack<StackModel>
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//-------------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
stack = Stack<StackModel>.createStack(with: [headlineBody, link])
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//-------------------------------------------------------
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
headlineBody.stylePageHeader()
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//------------------------------------------------------
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? HeadersH2LinkModel else { return }
|
||||
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||
link.set(with: model.link, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 121
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
headlineBody.stylePageHeader()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
//
|
||||
// HeadersH2LinkModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Lekshmi S on 24/06/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class HeadersH2LinkModel: HeaderModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "headerH2Link"
|
||||
public var headlineBody: HeadlineBodyModel
|
||||
public var link: LinkModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(headlineBody: HeadlineBodyModel, link: LinkModel) {
|
||||
self.headlineBody = headlineBody
|
||||
self.link = link
|
||||
super.init()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case headlineBody
|
||||
case link
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||
link = try typeContainer.decode(LinkModel.self, forKey: .link)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(headlineBody, forKey: .headlineBody)
|
||||
try container.encode(link, forKey: .link)
|
||||
}
|
||||
}
|
||||
@ -27,9 +27,13 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
||||
}
|
||||
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
topPadding = PaddingDefaultVerticalSpacing3
|
||||
bottomPadding = PaddingDefaultVerticalSpacing3
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -39,6 +39,12 @@ public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol {
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
subBody?.attributes = [LabelAttributeStrikeThroughModel(0, subBody?.text.count ?? 0)]
|
||||
subBody2?.attributes = [LabelAttributeStrikeThroughModel(0, subBody2?.text.count ?? 0)]
|
||||
|
||||
@ -33,9 +33,13 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setDefaults() {
|
||||
if topPadding == nil {
|
||||
topPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = Padding.Component.VerticalMarginSpacing
|
||||
}
|
||||
super.setDefaults()
|
||||
topPadding = PaddingDefaultVerticalSpacing3
|
||||
bottomPadding = PaddingDefaultVerticalSpacing3
|
||||
button.style = .secondary
|
||||
button.size = .tiny
|
||||
}
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
//
|
||||
// ListRightVariableToggleAllTextAndLinks.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 6/25/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class ListRightVariableToggleAllTextAndLinks: TableViewCell {
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//-----------------------------------------------------
|
||||
|
||||
public let toggle = Toggle()
|
||||
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//-----------------------------------------------------
|
||||
|
||||
public var stack: Stack<StackModel>!
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
stack = Stack<StackModel>.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: toggle, model: StackItemModel(horizontalAlignment: .fill))],
|
||||
axis: .horizontal)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//-----------------------------------------------------
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Molecular
|
||||
//-----------------------------------------------------
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListRightVariableToggleAllTextAndLinksModel else { return }
|
||||
toggle.set(with: model.toggle, delegateObject, additionalData)
|
||||
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
||||
updateAccessibilityLabel()
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 90
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// MARK: - Accessibility
|
||||
//----------------------------------------------------
|
||||
|
||||
func getAccessibilityMessage() -> String? {
|
||||
guard let toggleMessage = toggle.accessibilityLabel else {
|
||||
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
|
||||
}
|
||||
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
|
||||
return toggleMessage
|
||||
}
|
||||
return label + ", " + toggleMessage
|
||||
}
|
||||
|
||||
func updateAccessibilityLabel() {
|
||||
accessibilityHint = toggle.accessibilityHint
|
||||
accessibilityTraits = toggle.accessibilityTraits
|
||||
accessibilityValue = toggle.accessibilityValue
|
||||
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
|
||||
if !linkShowing && accessoryView == nil {
|
||||
// Make whole cell focusable if one action
|
||||
isAccessibilityElement = true
|
||||
accessibilityLabel = getAccessibilityMessage()
|
||||
} else {
|
||||
// Make buttons focusable.
|
||||
isAccessibilityElement = false
|
||||
var elements: [Any] = []
|
||||
if let accessoryView = accessoryView {
|
||||
accessoryView.accessibilityLabel = eyebrowHeadlineBodyLink.getAccessibilityMessage()
|
||||
elements.append(accessoryView)
|
||||
} else {
|
||||
toggle.accessibilityLabel = getAccessibilityMessage()
|
||||
}
|
||||
elements.append(toggle)
|
||||
|
||||
if linkShowing {
|
||||
elements.append(eyebrowHeadlineBodyLink.link)
|
||||
}
|
||||
accessibilityElements = elements
|
||||
}
|
||||
}
|
||||
|
||||
open override func accessibilityActivate() -> Bool {
|
||||
let activate = toggle.accessibilityActivate()
|
||||
accessibilityValue = toggle.accessibilityValue
|
||||
return activate
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
//
|
||||
// ListRightVariableToggleAllTextAndLinksModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 6/25/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class ListRightVariableToggleAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "listRVTgl"
|
||||
public var toggle: ToggleModel
|
||||
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(toggle: ToggleModel, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) {
|
||||
self.toggle = toggle
|
||||
self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink
|
||||
super.init()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case toggle
|
||||
case eyebrowHeadlineBodyLink
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
toggle = try typeContainer.decode(ToggleModel.self, forKey: .toggle)
|
||||
eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(toggle, forKey: .toggle)
|
||||
try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink)
|
||||
}
|
||||
}
|
||||
@ -33,10 +33,9 @@ public class ListTwoColumnPriceDetailsModel: ListItemModel, MoleculeModelProtoco
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = ListItemStyle.none
|
||||
super.setDefaults()
|
||||
|
||||
style = "none"
|
||||
|
||||
|
||||
if leftLabel.textColor == nil {
|
||||
leftLabel.textColor = Color(uiColor: .mvmCoolGray6)
|
||||
}
|
||||
|
||||
@ -33,8 +33,8 @@ public class ListFourColumnDataUsageDividerModel: ListItemModel, MoleculeModelPr
|
||||
}
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -33,8 +33,8 @@ public class ListOneColumnFullWidthTextDividerSubsectionModel: ListItemModel, Mo
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -33,8 +33,8 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .shortDivider
|
||||
super.setDefaults()
|
||||
style = "shortDivider"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -33,8 +33,8 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
|
||||
//--------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -35,8 +35,8 @@ public class ListThreeColumnBillChangesDividerModel: ListItemModel, MoleculeMode
|
||||
//-----------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -35,8 +35,8 @@ public class ListThreeColumnDataUsageDividerModel: ListItemModel, MoleculeModelP
|
||||
//-----------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -35,8 +35,8 @@ public class ListThreeColumnInternationalDataDividerModel: ListItemModel, Molecu
|
||||
//------------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -35,8 +35,8 @@ public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelPr
|
||||
//-----------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
leftHeadlineBody.style = .itemHeader
|
||||
centerHeadlineBody.style = .itemHeader
|
||||
rightHeadlineBody.style = .itemHeader
|
||||
|
||||
@ -35,8 +35,8 @@ public class ListThreeColumnSpeedTestDividerModel: ListItemModel, MoleculeModelP
|
||||
//-----------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -33,8 +33,8 @@ public class ListTwoColumnSubsectionDividerModel: ListItemModel, MoleculeModelPr
|
||||
//------------------------------------------------------
|
||||
|
||||
override public func setDefaults() {
|
||||
style = .tallDivider
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
@ -20,6 +20,7 @@ import Foundation
|
||||
|
||||
public var peakingUI: Bool?
|
||||
public var peakingArrowColor: Color?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -28,6 +29,7 @@ import Foundation
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case peakingUI
|
||||
case peakingArrowColor
|
||||
case analyticsData
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -38,6 +40,7 @@ import Foundation
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
peakingUI = try typeContainer.decodeIfPresent(Bool.self, forKey: .peakingUI)
|
||||
peakingArrowColor = try typeContainer.decodeIfPresent(Color.self, forKey: .peakingArrowColor)
|
||||
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
@ -46,5 +49,6 @@ import Foundation
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(peakingUI, forKey: .peakingUI)
|
||||
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,10 +24,10 @@ import Foundation
|
||||
|
||||
/// Defaults to set
|
||||
public override func setDefaults() {
|
||||
style = .sectionFooter
|
||||
super.setDefaults()
|
||||
hideArrow = true
|
||||
line = LineModel(type: .none)
|
||||
style = "sectionFooter"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -11,6 +11,7 @@ import Foundation
|
||||
|
||||
|
||||
@objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -19,7 +20,7 @@ import Foundation
|
||||
public var action: ActionModelProtocol?
|
||||
public var hideArrow: Bool?
|
||||
public var line: LineModel?
|
||||
public var style: String?
|
||||
public var style: ListItemStyle? = .standard
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -39,17 +40,39 @@ import Foundation
|
||||
|
||||
/// Defaults to set
|
||||
open override func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
setByStyle()
|
||||
}
|
||||
|
||||
/// Convenience function to set common values.
|
||||
open func set(useHorizontalMargins: Bool? = true, useVerticalMargins: Bool? = true, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) {
|
||||
if self.useHorizontalMargins == nil {
|
||||
self.useHorizontalMargins = useHorizontalMargins
|
||||
}
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
if self.useVerticalMargins == nil {
|
||||
self.useVerticalMargins = useVerticalMargins
|
||||
}
|
||||
if topPadding == nil {
|
||||
topPadding = 24
|
||||
if self.topPadding == nil {
|
||||
self.topPadding = topPadding
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = 24
|
||||
if self.bottomPadding == nil {
|
||||
self.bottomPadding = bottomPadding
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience function to set common values based on style.
|
||||
open func setByStyle() {
|
||||
guard let style = style else { return }
|
||||
switch style {
|
||||
case .standard:
|
||||
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: Padding.Component.VerticalMarginSpacing)
|
||||
case .shortDivider:
|
||||
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Four)
|
||||
case .tallDivider:
|
||||
set(topPadding: Padding.Twelve, bottomPadding: Padding.Four)
|
||||
case .sectionFooter:
|
||||
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: 0)
|
||||
case ListItemStyle.none:
|
||||
set(topPadding: 0, bottomPadding: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,6 +80,12 @@ import Foundation
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(style: ListItemStyle? = .standard, action: ActionModelProtocol?) {
|
||||
self.style = style
|
||||
self.action = action
|
||||
super.init()
|
||||
}
|
||||
|
||||
public override init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, useHorizontalMargins: Bool? = nil, leftPadding: CGFloat? = nil, rightPadding: CGFloat? = nil, useVerticalMargins: Bool? = nil, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) {
|
||||
super.init(horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment, useHorizontalMargins: useHorizontalMargins, leftPadding: leftPadding, rightPadding: rightPadding, useVerticalMargins: useVerticalMargins, topPadding: topPadding, bottomPadding: bottomPadding)
|
||||
}
|
||||
@ -75,7 +104,9 @@ import Foundation
|
||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||
if let style = try typeContainer.decodeIfPresent(ListItemStyle.self, forKey: .style) {
|
||||
self.style = style
|
||||
}
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
||||
public var backgroundColor: Color?
|
||||
public var tintColor: Color
|
||||
public var line: LineModel?
|
||||
public var alwaysShowBackButton = false
|
||||
public var alwaysShowBackButton: Bool?
|
||||
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "nav_back", action: ActionBackModel())
|
||||
public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||
public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||
@ -52,7 +52,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white)
|
||||
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .standard)
|
||||
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton) ?? false
|
||||
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton)
|
||||
if let backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol) = try typeContainer.decodeModelIfPresent(codingKey: .backButton) {
|
||||
self.backButton = backButton
|
||||
}
|
||||
@ -68,7 +68,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encode(tintColor, forKey: .tintColor)
|
||||
try container.encodeIfPresent(line, forKey: .line)
|
||||
try container.encode(alwaysShowBackButton, forKey: .alwaysShowBackButton)
|
||||
try container.encodeIfPresent(alwaysShowBackButton, forKey: .alwaysShowBackButton)
|
||||
try container.encodeModelIfPresent(backButton, forKey: .backButton)
|
||||
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
|
||||
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
|
||||
|
||||
@ -297,6 +297,12 @@ open class Carousel: View {
|
||||
cell.accessibilityElementsHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
func trackSwipeActionAnalyticsforIndex(_ index : Int){
|
||||
guard let itemModel = molecules?[index],
|
||||
let viewControllerObject = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol else { return }
|
||||
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: viewControllerObject, actionInformation: itemModel.toJSON(), additionalData: nil)
|
||||
}
|
||||
}
|
||||
|
||||
extension Carousel: UICollectionViewDelegateFlowLayout {
|
||||
@ -454,5 +460,7 @@ extension Carousel: UIScrollViewDelegate {
|
||||
// Cycle to other end if on buffer cell.
|
||||
pagingView?.currentIndex = pageIndex
|
||||
showPeaking(true)
|
||||
// track analyticsData
|
||||
trackSwipeActionAnalyticsforIndex(pageIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,4 +10,12 @@ import Foundation
|
||||
|
||||
|
||||
public protocol CarouselItemModelProtocol: ContainerModelProtocol {
|
||||
var analyticsData: JSONValueDictionary? { get set }
|
||||
}
|
||||
public extension CarouselItemModelProtocol {
|
||||
|
||||
var analyticsData: JSONValueDictionary? {
|
||||
get { return nil }
|
||||
set { analyticsData = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,12 +8,19 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum ListItemStyle: String, Codable {
|
||||
case standard
|
||||
case shortDivider
|
||||
case tallDivider
|
||||
case sectionFooter
|
||||
case none
|
||||
}
|
||||
|
||||
public protocol ListItemModelProtocol: ContainerModelProtocol {
|
||||
var line: LineModel? { get set }
|
||||
var action: ActionModelProtocol? { get set }
|
||||
var hideArrow: Bool? { get set }
|
||||
var style: String? { get set }
|
||||
var style: ListItemStyle? { get set }
|
||||
}
|
||||
|
||||
// Not a strict requirement.
|
||||
@ -24,7 +31,7 @@ public extension ListItemModelProtocol {
|
||||
set { }
|
||||
}
|
||||
|
||||
var style: String? {
|
||||
var style: ListItemStyle? {
|
||||
get { return nil }
|
||||
set { }
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ public protocol NavigationItemModelProtocol {
|
||||
var backgroundColor: Color? { get set }
|
||||
var tintColor: Color { get set }
|
||||
var line: LineModel? { get set }
|
||||
var alwaysShowBackButton: Bool { get set }
|
||||
var alwaysShowBackButton: Bool? { get set }
|
||||
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }
|
||||
var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
||||
var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
|
||||
|
||||
@ -9,6 +9,9 @@
|
||||
import Foundation
|
||||
|
||||
@objc public protocol TabBarProtocol {
|
||||
|
||||
var delegateObject: MVMCoreUIDelegateObject? { get set }
|
||||
|
||||
/// Should visually select the given tab index.
|
||||
@objc func highlightTab(at index: Int)
|
||||
|
||||
|
||||
@ -11,16 +11,23 @@ import Foundation
|
||||
public protocol TemplateProtocol: AnyObject {
|
||||
associatedtype TemplateModel: TemplateModelProtocol
|
||||
var templateModel: TemplateModel? { get set }
|
||||
|
||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel
|
||||
}
|
||||
|
||||
public extension TemplateProtocol where Self: ViewController {
|
||||
|
||||
func parseTemplate(json: [AnyHashable: Any]?) throws {
|
||||
guard let pageJSON = json else { return }
|
||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||
let decoder = JSONDecoder()
|
||||
try decoder.add(delegateObject: delegateObjectIVar)
|
||||
let templateModel = try decoder.decode(TemplateModel.self, from: data)
|
||||
self.templateModel = templateModel
|
||||
self.templateModel = try decodeTemplate(using: decoder, from: data)
|
||||
self.pageModel = templateModel as? MVMControllerModelProtocol
|
||||
}
|
||||
|
||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
||||
return try decoder.decode(TemplateModel.self, from: data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ListPageTemplateModel: ThreeLayerModelBase {
|
||||
@objcMembers open class ListPageTemplateModel: ThreeLayerModelBase {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
open override class var identifier: String {
|
||||
return "list"
|
||||
}
|
||||
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
|
||||
@ -49,7 +49,7 @@ import Foundation
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
open override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeModelsIfPresent(molecules, forKey: .molecules)
|
||||
|
||||
@ -28,6 +28,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
try super.parsePageJSON()
|
||||
}
|
||||
|
||||
// For subclassing the model.
|
||||
open func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ListPageTemplateModel {
|
||||
return try decoder.decode(ListPageTemplateModel.self, from: data)
|
||||
}
|
||||
|
||||
open override var loadObject: MVMCoreLoadObject? {
|
||||
didSet {
|
||||
guard loadObject != oldValue else { return }
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
||||
@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
|
||||
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
|
||||
public var anchorHeader: Bool = false
|
||||
public var header: MoleculeModelProtocol?
|
||||
public var anchorFooter: Bool = false
|
||||
|
||||
@ -31,60 +31,33 @@ import UIKit
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
// MARK: - Styling
|
||||
open func style(with styleString: String?) {
|
||||
guard let styleString = styleString else {
|
||||
return
|
||||
}
|
||||
switch styleString {
|
||||
case "standard":
|
||||
styleStandard()
|
||||
case "shortDivider":
|
||||
styleShortDivider()
|
||||
case "tallDivider":
|
||||
styleTallDivider()
|
||||
case "sectionFooter":
|
||||
styleFooter()
|
||||
case "none":
|
||||
styleNone()
|
||||
open func styleLine(with style: ListItemStyle?) {
|
||||
switch style {
|
||||
case .standard?:
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.standard)
|
||||
case .shortDivider?:
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.thin)
|
||||
case .tallDivider?:
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.thin)
|
||||
case .sectionFooter?:
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.none)
|
||||
case ListItemStyle.none?:
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.none)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
/// Default state.
|
||||
open func styleStandard() {
|
||||
listItemModel?.topPadding = 24
|
||||
listItemModel?.bottomPadding = 24
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.standard)
|
||||
MFStyler.setMarginsFor(self, size: MVMCoreUIUtility.getWidth(), defaultHorizontal: true, top: Padding.Component.VerticalMarginSpacing, bottom: Padding.Component.VerticalMarginSpacing)
|
||||
styleLine(with: .standard)
|
||||
}
|
||||
|
||||
open func styleTallDivider() {
|
||||
listItemModel?.topPadding = 48
|
||||
listItemModel?.bottomPadding = 16
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.thin)
|
||||
}
|
||||
|
||||
open func styleShortDivider() {
|
||||
listItemModel?.topPadding = 32
|
||||
listItemModel?.bottomPadding = 16
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.thin)
|
||||
}
|
||||
|
||||
open func styleFooter() {
|
||||
listItemModel?.topPadding = 24
|
||||
listItemModel?.bottomPadding = 0
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.none)
|
||||
}
|
||||
|
||||
open func styleNone() {
|
||||
listItemModel?.topPadding = 0
|
||||
listItemModel?.bottomPadding = 0
|
||||
topSeparatorView?.setStyle(.none)
|
||||
bottomSeparatorView?.setStyle(.none)
|
||||
}
|
||||
|
||||
|
||||
/// Adds the molecule to the view.
|
||||
open func addMolecule(_ molecule: MoleculeViewProtocol) {
|
||||
contentView.addSubview(molecule)
|
||||
@ -156,7 +129,7 @@ import UIKit
|
||||
guard let model = model as? ListItemModelProtocol else { return }
|
||||
|
||||
self.listItemModel = model
|
||||
style(with: model.style)
|
||||
styleLine(with: model.style)
|
||||
|
||||
// Add the caret if there is an action and it's not declared hidden.
|
||||
if !customAccessoryView {
|
||||
|
||||
@ -94,9 +94,10 @@ import UIKit
|
||||
try parsePageJSON()
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
self.handleNewDataAndUpdateUI()
|
||||
// If the screen is showing, can update the navigation controller.
|
||||
if MVMCoreUIUtility.getCurrentVisibleController() == self.manager ?? self {
|
||||
self.setNavigationController()
|
||||
|
||||
// Update navigation bar if showing.
|
||||
if MVMCoreUIUtility.getCurrentVisibleController() == self {
|
||||
self.setNavigationBar()
|
||||
}
|
||||
})
|
||||
} catch {
|
||||
@ -119,6 +120,7 @@ import UIKit
|
||||
return true
|
||||
} catch let parsingError {
|
||||
// Log all parsing errors and fail load.
|
||||
handleLoggingFor(parsingError: parsingError)
|
||||
if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) {
|
||||
errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||
error.pointee = errorObject
|
||||
@ -127,9 +129,36 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
func handleLoggingFor(parsingError: Error) {
|
||||
if let registryError = parsingError as? ModelRegistry.Error {
|
||||
switch (registryError) {
|
||||
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })")
|
||||
case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath):
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })")
|
||||
default:
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)")
|
||||
}
|
||||
}
|
||||
if let decodingError = parsingError as? DecodingError {
|
||||
switch (decodingError) {
|
||||
case .keyNotFound(let codingKey, let context):
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })")
|
||||
case .valueNotFound(_, let context):
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })")
|
||||
case .typeMismatch(_, let context):
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })")
|
||||
case .dataCorrupted(let context):
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })")
|
||||
@unknown default:
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func parsePageJSON() throws {
|
||||
}
|
||||
|
||||
|
||||
open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||
guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType),
|
||||
!modulesRequired.isEmpty else { return true }
|
||||
@ -168,12 +197,6 @@ import UIKit
|
||||
|
||||
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
|
||||
open func handleNewData() {
|
||||
// TODO: remove legacy. Temporary, convert legacy to navigation model.
|
||||
if pageModel?.navigationBar == nil {
|
||||
let navigationItem = createDefaultLegacyNavigationModel()
|
||||
pageModel?.navigationBar = navigationItem
|
||||
}
|
||||
|
||||
if formValidator == nil {
|
||||
let rules = pageModel?.formRules
|
||||
formValidator = FormValidator(rules)
|
||||
@ -182,20 +205,43 @@ import UIKit
|
||||
if let backgroundColor = pageModel?.backgroundColor {
|
||||
view.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
// Sets up the navigation item based on the data.
|
||||
setNavigationItem()
|
||||
}
|
||||
|
||||
// MARK: - Navigation Item (Move to model base)
|
||||
open func setNavigationController() {
|
||||
|
||||
open func getNavigationModel() -> NavigationItemModelProtocol? {
|
||||
// TODO: remove legacy. Temporary, convert legacy to navigation model.
|
||||
if pageModel?.navigationBar == nil {
|
||||
let navigationItem = createDefaultLegacyNavigationModel()
|
||||
pageModel?.navigationBar = navigationItem
|
||||
}
|
||||
return pageModel?.navigationBar
|
||||
}
|
||||
|
||||
/// Sets the navigation item for this view controller.
|
||||
open func setNavigationItem() {
|
||||
guard let navigationItemModel = getNavigationModel(),
|
||||
let navigationController = navigationController else { return }
|
||||
|
||||
// We additionally want our left items
|
||||
navigationItem.leftItemsSupplementBackButton = true
|
||||
|
||||
// Utilize helper function to set the navigation item state.
|
||||
NavigationController.setNavigationItem(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: self)
|
||||
}
|
||||
|
||||
/// Sets the appearance of the navigation bar based on the model.
|
||||
open func setNavigationBar() {
|
||||
let viewController = manager ?? self
|
||||
guard let navigationItemModel = pageModel?.navigationBar,
|
||||
guard let navigationItemModel = getNavigationModel(),
|
||||
let navigationController = viewController.navigationController else {
|
||||
MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate()
|
||||
return
|
||||
}
|
||||
|
||||
// We additionally want our left items
|
||||
navigationItem.leftItemsSupplementBackButton = true
|
||||
|
||||
// Utilize helper function to set the split view and navigation item state.
|
||||
MVMCoreUISplitViewController.setSplitViewController(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: isMasterInitiallyAccessible(), rightPanelAccessible: isSupportInitiallyAccessible(), progress: bottomProgress() ?? 0)
|
||||
}
|
||||
@ -249,6 +295,7 @@ import UIKit
|
||||
open func updateTabBar() {
|
||||
guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self,
|
||||
let tabModel = pageModel as? TabPageModelProtocol else { return }
|
||||
MVMCoreUISplitViewController.main()?.tabBar?.delegateObject = delegateObjectIVar
|
||||
if let index = tabModel.tabBarIndex {
|
||||
MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index)
|
||||
}
|
||||
@ -308,7 +355,7 @@ import UIKit
|
||||
|
||||
open func pageShown() {
|
||||
// Update the navigation bar ui when view is appearing.
|
||||
setNavigationController()
|
||||
setNavigationBar()
|
||||
|
||||
// Update tab if needed.
|
||||
updateTabBar()
|
||||
@ -425,7 +472,7 @@ import UIKit
|
||||
|
||||
// Reset the navigation state.
|
||||
public func splitViewDidReset() {
|
||||
setNavigationController()
|
||||
setNavigationBar()
|
||||
}
|
||||
|
||||
// MARK: - UITextFieldDelegate (Check if this is still needed)
|
||||
|
||||
@ -71,149 +71,153 @@ extension UIColor {
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #D52B1E
|
||||
public static let mvmRed = UIColor.color8Bits(red: 213, green: 43, blue: 30)
|
||||
public static let mvmRed = UIColor.assetColor(named: "red")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Pink
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #D90368
|
||||
public static let mvmPink = UIColor.color8Bits(red: 217, green: 3, blue: 104)
|
||||
public static let mvmPink = UIColor.assetColor(named: "pink")
|
||||
|
||||
/// HEX: #F2ABCD
|
||||
public static let mvmPink33 = UIColor.color8Bits(red: 242, green: 171, blue: 205)
|
||||
public static let mvmPink33 = UIColor.assetColor(named: "pink33")
|
||||
|
||||
/// HEX: #E6589B
|
||||
public static let mvmPink66 = UIColor.color8Bits(red: 230, green: 88, blue: 155)
|
||||
public static let mvmPink66 = UIColor.assetColor(named: "pink66")
|
||||
|
||||
/// HEX: #B31C63
|
||||
public static let mvmPinkShade1 = UIColor.color8Bits(red: 179, green: 28, blue: 99)
|
||||
public static let mvmPinkShade1 = UIColor.assetColor(named: "pinkShade1")
|
||||
|
||||
/// HEX: #830842
|
||||
public static let mvmPinkShade2 = UIColor.color8Bits(red: 131, green: 8, blue: 66)
|
||||
public static let mvmPinkShade2 = UIColor.assetColor(named: "pinkShade2")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Purple
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #8C00AC
|
||||
public static let mvmPurple = UIColor.color8Bits(red: 140, green: 0, blue: 172)
|
||||
public static let mvmPurple = UIColor.assetColor(named: "purple")
|
||||
|
||||
/// HEX: #D9ABE4
|
||||
public static let mvmPurple33 = UIColor.color8Bits(red: 217, green: 171, blue: 228)
|
||||
public static let mvmPurple33 = UIColor.assetColor(named: "purple33")
|
||||
|
||||
/// HEX: #B356C8
|
||||
public static let mvmPurple66 = UIColor.color8Bits(red: 179, green: 86, blue: 200)
|
||||
public static let mvmPurple66 = UIColor.assetColor(named: "purple66")
|
||||
|
||||
/// HEX: #6C177F
|
||||
public static let mvmPurpleShade1 = UIColor.color8Bits(red: 108, green: 23, blue: 127)
|
||||
public static let mvmPurpleShade1 = UIColor.assetColor(named: "purpleShade1")
|
||||
|
||||
/// HEX: #4A0E58
|
||||
public static let mvmPurpleShade2 = UIColor.color8Bits(red: 74, green: 14, blue: 88)
|
||||
public static let mvmPurpleShade2 = UIColor.assetColor(named: "purpleShade2")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Orange
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #ED7000
|
||||
public static let mvmOrange = UIColor.color8Bits(red: 237, green: 112, blue: 0)
|
||||
public static let mvmOrange = UIColor.assetColor(named: "orange")
|
||||
|
||||
/// HEX: #CC4D0F
|
||||
public static let mvmOrangeAA = UIColor.color8Bits(red: 204, green: 77, blue: 15)
|
||||
public static let mvmOrangeAA = UIColor.assetColor(named: "orangeAA")
|
||||
|
||||
/// HEX: #F9D0AB
|
||||
public static let mvmOrange33 = UIColor.color8Bits(red: 249, green: 208, blue: 171)
|
||||
public static let mvmOrange33 = UIColor.assetColor(named: "orange33")
|
||||
|
||||
/// HEX: #F3A157
|
||||
public static let mvmOrange66 = UIColor.color8Bits(red: 243, green: 161, blue: 87)
|
||||
public static let mvmOrange66 = UIColor.assetColor(named: "orange66")
|
||||
|
||||
/// HEX: #CB5F00
|
||||
public static let mvmOrangeShade1 = UIColor.color8Bits(red: 203, green: 95, blue: 0)
|
||||
public static let mvmOrangeShade1 = UIColor.assetColor(named: "orangeShade1")
|
||||
|
||||
/// HEX: #984700
|
||||
public static let mvmOrangeShade2 = UIColor.color8Bits(red: 152, green: 71, blue: 0)
|
||||
public static let mvmOrangeShade2 = UIColor.assetColor(named: "orangeShade2")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Green
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #008330
|
||||
public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 48)
|
||||
public static let mvmGreen = UIColor.assetColor(named: "green")
|
||||
|
||||
/// HEX: #ABE4BF
|
||||
public static let mvmGreen33 = UIColor.color8Bits(red: 171, green: 228, blue: 191)
|
||||
public static let mvmGreen33 = UIColor.assetColor(named: "green33")
|
||||
|
||||
/// HEX: #57C880
|
||||
public static let mvmGreen66 = UIColor.color8Bits(red: 87, green: 200, blue: 128)
|
||||
public static let mvmGreen66 = UIColor.assetColor(named: "green66")
|
||||
|
||||
/// HEX: #0F5B25
|
||||
public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37)
|
||||
public static let mvmGreenShade2 = UIColor.assetColor(named: "greenShade2")
|
||||
|
||||
/// HEX: #00AC3E
|
||||
public static let mvmGreenInverted = UIColor.color8Bits(red: 0, green: 172, blue: 62)
|
||||
public static let mvmGreenInverted = UIColor.assetColor(named: "greenInverted")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Blue
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #0077B4
|
||||
public static let mvmBlue = UIColor.color8Bits(red: 0, green: 119, blue: 180)
|
||||
public static let mvmBlue = UIColor.assetColor(named: "blue")
|
||||
|
||||
/// HEX: #ABD8EF
|
||||
public static let mvmBlue33 = UIColor.color8Bits(red: 171, green: 216, blue: 239)
|
||||
public static let mvmBlue33 = UIColor.assetColor(named: "blue33")
|
||||
|
||||
/// HEX: #57B1DF
|
||||
public static let mvmBlue66 = UIColor.color8Bits(red: 87, green: 177, blue: 223)
|
||||
public static let mvmBlue66 = UIColor.assetColor(named: "blue66")
|
||||
|
||||
/// HEX: #136598
|
||||
public static let mvmBlueShade1 = UIColor.color8Bits(red: 19, green: 101, blue: 152)
|
||||
public static let mvmBlueShade1 = UIColor.assetColor(named: "blueShade1")
|
||||
|
||||
/// HEX: #0B4467
|
||||
public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103)
|
||||
public static let mvmBlueShade2 = UIColor.assetColor(named: "blueShade2")
|
||||
|
||||
/// HEX: #0088CE
|
||||
public static let mvmBlueInverted = UIColor.color8Bits(red: 0, green: 136, blue: 206)
|
||||
public static let mvmBlueInverted = UIColor.assetColor(named: "blueInverted")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Yellow
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #FFBC3D
|
||||
public static let mvmYellow = UIColor.color8Bits(red: 255, green: 188, blue: 61)
|
||||
public static let mvmYellow = UIColor.assetColor(named: "yellow")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Gray
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #F6F6F6
|
||||
public static let mvmCoolGray1 = UIColor.grayscale(rgb: 246)
|
||||
public static let mvmCoolGray1 = UIColor.assetColor(named: "coolGray1")
|
||||
|
||||
/// HEX: #D8DADA
|
||||
public static let mvmCoolGray3 = UIColor.color8Bits(red: 216, green: 218, blue: 218)
|
||||
public static let mvmCoolGray3 = UIColor.assetColor(named: "coolGray3")
|
||||
|
||||
/// HEX: #747676
|
||||
public static let mvmCoolGray6 = UIColor.color8Bits(red: 116, green: 118, blue: 118)
|
||||
public static let mvmCoolGray6 = UIColor.assetColor(named: "coolGray6")
|
||||
|
||||
/// HEX: #333333
|
||||
public static let mvmCoolGray10 = UIColor.grayscale(rgb: 51)
|
||||
public static let mvmCoolGray10 = UIColor.assetColor(named: "coolGray10")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - VZ UP Brand
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #F9D542
|
||||
public static let vzupGold1 = UIColor.color8Bits(red: 249, green: 213, blue: 66)
|
||||
public static let vzupGold1 = UIColor.assetColor(named: "upGold1")
|
||||
|
||||
/// HEX: #F4CA53
|
||||
public static let vzupGold2 = UIColor.color8Bits(red: 244, green: 202, blue: 83)
|
||||
public static let vzupGold2 = UIColor.assetColor(named: "upGold2")
|
||||
|
||||
/// HEX: #CC9B2D
|
||||
public static let vzupGold3 = UIColor.color8Bits(red: 204, green: 155, blue: 45)
|
||||
public static let vzupGold3 = UIColor.assetColor(named: "upGold3")
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Functions
|
||||
//--------------------------------------------------
|
||||
|
||||
public static func assetColor(named name: String) -> UIColor {
|
||||
return UIColor(named: name, in: MVMCoreUIUtility.bundleForMVMCoreUI(), compatibleWith: nil)!
|
||||
}
|
||||
|
||||
/// Convenience to get a grayscale UIColor where the same value is used for red, green, and blue.
|
||||
public class func grayscale(rgb: Int, alpha: CGFloat = 1.0) -> UIColor {
|
||||
|
||||
@ -299,7 +303,7 @@ extension UIColor {
|
||||
} else if numberOfComponents == 2 {
|
||||
// Monochromatic color space
|
||||
let value = Int(CGFloat(components[0]) * 255)
|
||||
|
||||
|
||||
// If alpha of color is less than 1.0 then alpha hex is relevant.
|
||||
if components[1] < 1.0 {
|
||||
let alpha = Int(CGFloat(components[1]) * 255)
|
||||
|
||||
6
MVMCoreUI/Categories/colors.xcassets/Contents.json
Normal file
6
MVMCoreUI/Categories/colors.xcassets/Contents.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x00",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xB4",
|
||||
"green" : "0x77"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xAB",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xEF",
|
||||
"green" : "0xD8"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x57",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xDF",
|
||||
"green" : "0xB1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x00",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xCE",
|
||||
"green" : "0x88"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x13",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x98",
|
||||
"green" : "0x65"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x0B",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x67",
|
||||
"green" : "0x44"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF6",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xF6",
|
||||
"green" : "0xF6"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x33",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x33",
|
||||
"green" : "0x33"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xD8",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xDA",
|
||||
"green" : "0xDA"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x74",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x76",
|
||||
"green" : "0x76"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x00",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x30",
|
||||
"green" : "0x83"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xAB",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xBF",
|
||||
"green" : "0xE4"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x57",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x80",
|
||||
"green" : "0xC8"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x00",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x3E",
|
||||
"green" : "0xAC"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x0F",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x25",
|
||||
"green" : "0x5B"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xED",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x70"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF9",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xAB",
|
||||
"green" : "0xD0"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF3",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x57",
|
||||
"green" : "0xA1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xCC",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x0F",
|
||||
"green" : "0x4D"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xCB",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x5F"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x98",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x47"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xD9",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x68",
|
||||
"green" : "0x03"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF2",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xCD",
|
||||
"green" : "0xAB"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xE6",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x9B",
|
||||
"green" : "0x58"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xB3",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x63",
|
||||
"green" : "0x1C"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x83",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x42",
|
||||
"green" : "0x08"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x8C",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xAC",
|
||||
"green" : "0x00"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xD9",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xE4",
|
||||
"green" : "0xAB"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xB3",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xC8",
|
||||
"green" : "0x56"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x6C",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x7F",
|
||||
"green" : "0x17"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0x4A",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x58",
|
||||
"green" : "0x0E"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xD5",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x1E",
|
||||
"green" : "0x2B"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF9",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x42",
|
||||
"green" : "0xD5"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xF4",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x53",
|
||||
"green" : "0xCA"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xCC",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x2D",
|
||||
"green" : "0x9B"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"red" : "0xFF",
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x3D",
|
||||
"green" : "0xBC"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -43,17 +43,27 @@ import UIKit
|
||||
return navigationController
|
||||
}
|
||||
|
||||
/// Convenience function for setting the navigation item.
|
||||
public static func setNavigationItem(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
|
||||
viewController.navigationItem.title = navigationItemModel.title
|
||||
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
|
||||
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
|
||||
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
}
|
||||
|
||||
/// Convenience function for setting the navigation buttons.
|
||||
public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
|
||||
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
|
||||
var leftItems: [UIBarButtonItem] = []
|
||||
if let backButtonModel = navigationItemModel.backButton,
|
||||
navigationController.viewControllers.count > 1 || navigationItemModel.alwaysShowBackButton {
|
||||
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
}
|
||||
if let leftItemModels = navigationItemModel.additionalLeftButtons {
|
||||
for item in leftItemModels {
|
||||
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
if navigationItemModel.alwaysShowBackButton != false {
|
||||
if let backButtonModel = navigationItemModel.backButton,
|
||||
navigationController.viewControllers.count > 1 || navigationItemModel.alwaysShowBackButton ?? false {
|
||||
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
}
|
||||
if let leftItemModels = navigationItemModel.additionalLeftButtons {
|
||||
for item in leftItemModels {
|
||||
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil
|
||||
@ -68,11 +78,7 @@ import UIKit
|
||||
}
|
||||
|
||||
/// Convenience function for setting the navigation bar ui, except for the buttons.
|
||||
public static func setNavigationUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
|
||||
viewController.navigationItem.title = navigationItemModel.title
|
||||
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
|
||||
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
|
||||
|
||||
public static func setNavigationBarUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
|
||||
navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true)
|
||||
navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white
|
||||
|
||||
@ -88,17 +94,19 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience function for setting navigation bar with model.
|
||||
public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
|
||||
setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
}
|
||||
|
||||
/// Convenience setter for legacy files
|
||||
public static func set(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws {
|
||||
public static func setNavigationItem(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws {
|
||||
guard let barModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
|
||||
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
|
||||
}
|
||||
set(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
|
||||
setNavigationItem(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
|
||||
}
|
||||
|
||||
/// Convenience setter for legacy files
|
||||
public static func setNavigationBarUI(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws {
|
||||
guard let barModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
|
||||
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
|
||||
}
|
||||
setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ public extension MVMCoreUISplitViewController {
|
||||
guard let splitView = MVMCoreUISplitViewController.main(),
|
||||
navigationController == splitView.navigationController,
|
||||
navigationController.topViewController == viewController else {
|
||||
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
return
|
||||
}
|
||||
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress)
|
||||
@ -27,7 +27,7 @@ public extension MVMCoreUISplitViewController {
|
||||
// Setup the panels.
|
||||
setupPanels()
|
||||
|
||||
NavigationController.setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
|
||||
setLeftPanelIsAccessible(leftPanelAccessible ?? leftPanelIsAccessible, for: viewController, updateNavigationButtons: false)
|
||||
setRightPanelIsAccessible(rightPanelAccessible ?? rightPanelIsAccessible, for: viewController, updateNavigationButtons: false)
|
||||
@ -48,13 +48,15 @@ public extension MVMCoreUISplitViewController {
|
||||
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
|
||||
|
||||
// Add back button first.
|
||||
if let backButtonModel = navigationItemModel?.backButton {
|
||||
if navigationController.viewControllers.count > 1 || navigationItemModel!.alwaysShowBackButton {
|
||||
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
if navigationItemModel?.alwaysShowBackButton != false {
|
||||
if let backButtonModel = navigationItemModel?.backButton {
|
||||
if navigationController.viewControllers.count > 1 || navigationItemModel!.alwaysShowBackButton ?? false {
|
||||
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
|
||||
}
|
||||
} else if let backButton = backButton,
|
||||
navigationController.viewControllers.count > 1 {
|
||||
leftItems.append(backButton)
|
||||
}
|
||||
} else if let backButton = backButton,
|
||||
navigationController.viewControllers.count > 1 {
|
||||
leftItems.append(backButton)
|
||||
}
|
||||
|
||||
// Add the panel button after the back button.
|
||||
@ -115,7 +117,7 @@ public extension MVMCoreUISplitViewController {
|
||||
guard let splitView = MVMCoreUISplitViewController.main(),
|
||||
navigationController == splitView.navigationController,
|
||||
navigationController.topViewController == viewController else {
|
||||
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
|
||||
return
|
||||
}
|
||||
let progress = progress?.floatValue
|
||||
|
||||
@ -13,7 +13,7 @@ public extension Dictionary {
|
||||
throw ModelRegistry.Error.decoderOther(message: "Dictionary is not of type [String: Any]")
|
||||
}
|
||||
guard let actionType = ModelRegistry.getType(for: castedSelf.stringForkey(KeyActionType), with: ActionModelProtocol.self) else {
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||
throw ModelRegistry.Error.decoderErrorModelNotMapped()
|
||||
}
|
||||
guard let actionModel = try actionType.decode(jsonDict: castedSelf) as? ActionModelProtocol else {
|
||||
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol")
|
||||
|
||||
@ -17,8 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller;
|
||||
|
||||
// Action Logging
|
||||
- (void)defaultLogActionForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -13,10 +13,10 @@
|
||||
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller {
|
||||
}
|
||||
|
||||
- (void)defaultLogActionForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
|
||||
}
|
||||
|
||||
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
// MARK: Accessibility
|
||||
"AccCloseButton" = "Close";
|
||||
"swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select.";
|
||||
|
||||
"AccDisabled" = "Disabled";
|
||||
"index_string_of_total" = "%@ of %d";
|
||||
|
||||
// MARK: Tab
|
||||
"AccTab" = ", tab";
|
||||
@ -59,7 +60,6 @@
|
||||
"radio_not_selected_state" = "Not Selected";
|
||||
"radio_desc_state" = "Option";
|
||||
|
||||
|
||||
// MARK: Switch / Toggle
|
||||
"mfswitch_buttonlabel" = "Switch Button";
|
||||
"Toggle_buttonlabel" = "Toggle Button";
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
// Accessibility
|
||||
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
|
||||
"AccDisabled" = "desactivado";
|
||||
"index_string_of_total" = "%@ de %d";
|
||||
|
||||
"AccCloseButton" = "Cerrar";
|
||||
// Tab
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
// Accessibility
|
||||
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
|
||||
"AccDisabled" = "desactivado";
|
||||
|
||||
"AccCloseButton" = "Cerrar";
|
||||
// Tab
|
||||
|
||||
@ -374,6 +374,7 @@
|
||||
weakSelf.shortViewHeight.active = NO;
|
||||
} completion:^(BOOL finished) {
|
||||
[weakSelf.viewToLayout layoutIfNeeded];
|
||||
weakSelf.accessibilityElements = @[weakSelf.shortView.label];
|
||||
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
|
||||
[MVMCoreDispatchUtility performBlockInBackground:^{
|
||||
// Must notify animation delegate when animating finished.
|
||||
|
||||
@ -46,6 +46,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// Removes any format.
|
||||
+ (nullable NSString *)removeMdnFormat:(nullable NSString *)mdn;
|
||||
|
||||
/// Returns an ordinal formatted string for a number.
|
||||
+ (nullable NSString *)getOrdinalStringForIndex:(nonnull NSNumber *)number;
|
||||
|
||||
#pragma mark - Validations
|
||||
|
||||
// Will validate passed string on corresponding regular expression
|
||||
|
||||
@ -113,6 +113,12 @@
|
||||
return mdn;
|
||||
}
|
||||
|
||||
+ (nullable NSString *)getOrdinalStringForIndex:(nonnull NSNumber *)number {
|
||||
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
|
||||
formatter.numberStyle = NSNumberFormatterOrdinalStyle;
|
||||
return [formatter stringFromNumber:number];
|
||||
}
|
||||
|
||||
#pragma mark - Validations
|
||||
|
||||
+ (BOOL)validateString:(nonnull NSString *)string withRegularExpression:(nonnull NSString *)regExpression {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user