Merge branch 'develop' into feature/new_loading_spinner

This commit is contained in:
Kevin G Christiano 2020-05-22 09:00:02 -04:00
commit cf5610ea26
21 changed files with 457 additions and 96 deletions

View File

@ -116,6 +116,8 @@
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */; };
32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */; };
522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; };
522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */; };
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */; };
@ -255,7 +257,7 @@
D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */; };
D20923592450ECE00044AD09 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20923582450ECE00044AD09 /* TableView.swift */; };
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; };
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; };
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */; };
D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; };
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */; };
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; };
@ -273,7 +275,11 @@
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 */; };
D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */; };
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; };
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; };
D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; };
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; };
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; };
D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; };
@ -297,6 +303,7 @@
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; };
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; };
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; };
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D272F5F82473163100BD1A8F /* BarButtonItem.swift */; };
D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; };
D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; };
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
@ -537,6 +544,8 @@
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = "<group>"; };
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinksModel.swift; sourceTree = "<group>"; };
32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinks.swift; sourceTree = "<group>"; };
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = "<group>"; };
522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinksModel.swift; sourceTree = "<group>"; };
52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinks.swift; sourceTree = "<group>"; };
@ -676,7 +685,7 @@
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerModelBase.swift; sourceTree = "<group>"; };
D20923582450ECE00044AD09 /* TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableView.swift; sourceTree = "<group>"; };
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = "<group>"; };
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModel.swift; sourceTree = "<group>"; };
D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = "<group>"; };
@ -694,7 +703,11 @@
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>"; };
D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = "<group>"; };
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = "<group>"; };
D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = "<group>"; };
D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = "<group>"; };
D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
@ -717,6 +730,7 @@
D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = "<group>"; };
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = "<group>"; };
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
D272F5F82473163100BD1A8F /* BarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarButtonItem.swift; sourceTree = "<group>"; };
D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = "<group>"; };
D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = "<group>"; };
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = "<group>"; };
@ -864,6 +878,7 @@
children = (
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */,
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */,
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
@ -872,6 +887,8 @@
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */,
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */,
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */,
);
path = ModelProtocols;
sourceTree = "<group>";
@ -1293,6 +1310,8 @@
0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */,
AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */,
AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */,
32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */,
32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */,
);
path = LeftVariable;
sourceTree = "<group>";
@ -1349,6 +1368,15 @@
path = TwoColumn;
sourceTree = "<group>";
};
D2509ED42472EE0B001BFB9D /* NavigationBar */ = {
isa = PBXGroup;
children = (
D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */,
D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */,
);
path = NavigationBar;
sourceTree = "<group>";
};
D253BB9A24587023002DE544 /* OtherContainers */ = {
isa = PBXGroup;
children = (
@ -1490,6 +1518,7 @@
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
isa = PBXGroup;
children = (
D2509ED42472EE0B001BFB9D /* NavigationBar */,
D253BB9A24587023002DE544 /* OtherContainers */,
D22B38E923F4E07800490EF6 /* DesignedComponents */,
D22479912316A9EF003FCCF9 /* Items */,
@ -1503,7 +1532,6 @@
012A88EB238F084D00FE3DA1 /* FooterModel.swift */,
D274CA322236A78900B01B62 /* FooterView.swift */,
D260105723CF9CC500764D80 /* Doughnut */,
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */,
);
path = Molecules;
sourceTree = "<group>";
@ -1798,6 +1826,7 @@
D264FAA92440F97600D98315 /* CollectionView.swift */,
0A5D59C323AD488600EFD9E9 /* Protocols */,
0A7918F423F5E7EA00772FF4 /* ImageView.swift */,
D272F5F82473163100BD1A8F /* BarButtonItem.swift */,
);
path = BaseClasses;
sourceTree = "<group>";
@ -1956,6 +1985,8 @@
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */,
32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */,
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
C07065C42395677300FBF997 /* Link.swift in Sources */,
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */,
@ -1982,6 +2013,7 @@
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */,
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */,
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */,
0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */,
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
@ -2098,6 +2130,7 @@
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */,
94F6516D2437954100631BF9 /* Tabs.swift in Sources */,
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
@ -2157,11 +2190,13 @@
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */,
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */,
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */,
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */,
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */,
944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */,
D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */,
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */,
011D958524042432000E3791 /* RulesProtocol.swift in Sources */,
AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */,
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */,
@ -2199,7 +2234,7 @@
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */,
@ -2261,6 +2296,7 @@
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */,
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */,
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */,
27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */,

View File

@ -677,6 +677,9 @@ public typealias ActionBlock = () -> ()
@objc public func updateView(_ size: CGFloat) {
scaleSize = size as NSNumber
// This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space.
preferredMaxLayoutWidth = size
if let originalAttributedString = originalAttributedString {
let attributedString = NSMutableAttributedString(attributedString: originalAttributedString)
attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length))

View File

@ -55,6 +55,10 @@ import UIKit
public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) {
self.init(frame: .zero)
addLine(to: view, edge: edge, useMargin: useMargin)
}
open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) {
view.addSubview(self)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values))
}

View File

@ -148,6 +148,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)

View File

@ -0,0 +1,60 @@
//
// ListLeftVariableNumberedListAllTextAndLinks.swift
// MVMCoreUI
//
// Created by Subhankar Acharya on 21/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListLeftVariableNumberedListAllTextAndLinks: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public let leftLabel = Label.createLabelTitle2XLarge(true)
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
public var stack: Stack<StackModel>
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)),
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
axis: .horizontal)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//--------------------------------------------------
// MARK: - Life Cycle
//--------------------------------------------------
override open func setupView() {
super.setupView()
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? ListLeftVariableNumberedListAllTextAndLinksModel else { return }
leftLabel.text = String(model.number)
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 140
}
open override func reset() {
super.reset()
leftLabel.styleTitle2XLarge(true)
}
}

View File

@ -0,0 +1,42 @@
//
// ListLeftVariableNumberedListAllTextAndLinksModel.swift
// MVMCoreUI
//
// Created by Subhankar Acharya on 21/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListLeftVariableNumberedListAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "listLVNAll"
public var number: Int
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
public init(number: Int, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) {
self.number = number
self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink
super.init()
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case number
case eyebrowHeadlineBodyLink
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
number = try typeContainer.decode(Int.self, forKey: .number)
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(number, forKey: .number)
try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink)
}
}

View File

@ -8,7 +8,7 @@
import Foundation
open class CarouselItem: MoleculeCollectionViewCell {
open class CarouselItem: MoleculeCollectionViewCell, CarouselItemProtocol {
open var allowsPeaking = false
var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate))

View File

@ -0,0 +1,41 @@
//
// NavigationItemButtonModel.swift
//
//
// Created by Scott Pfeil on 5/18/20.
//
import Foundation
public class NavigationItemButtonModel: Codable {
var imageName: String
var action: ActionModelProtocol
public init(with imageName: String, action: ActionModelProtocol) {
self.imageName = imageName
self.action = action
}
private enum CodingKeys: String, CodingKey {
case imageName
case action
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
imageName = try typeContainer.decode(String.self, forKey: .imageName)
action = try typeContainer.decodeModel(codingKey: .action)
}
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(imageName, forKey: .imageName)
try container.encodeModel(action, forKey: .action)
}
/// Convenience function that creates a BarButtonItem for the model.
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem {
let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil)
return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
}
}

View File

@ -8,48 +8,7 @@
import Foundation
public protocol NavigationItemModelProtocol {
var title: String? { get set }
var hidden: Bool { get set }
var backgroundColor: Color? { get set }
var translucent: Bool { get set }
var tintColor: Color { get set }
var line: LineModel? { get set }
var showLeftPanelButton: Bool { get set }
var showRightPanelButton: Bool { get set }
var backButton: NavigationItemButtonModel? { get set }
var additionalLeftButtons: [NavigationItemButtonModel]? { get set }
var additionalRightButtons: [NavigationItemButtonModel]? { get set }
}
public class NavigationItemButtonModel: Codable {
var imageName: String
var action: ActionModelProtocol
public init(with imageName: String, action: ActionModelProtocol) {
self.imageName = imageName
self.action = action
}
private enum CodingKeys: String, CodingKey {
case imageName
case action
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
imageName = try typeContainer.decode(String.self, forKey: .imageName)
action = try typeContainer.decodeModel(codingKey: .action)
}
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(imageName, forKey: .imageName)
try container.encodeModel(action, forKey: .action)
}
}
public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationItemModelProtocol, MoleculeModelProtocol {
public class var identifier: String {
return "navigationBar"
}
@ -60,12 +19,14 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
public var translucent: Bool
public var tintColor: Color
public var line: LineModel?
public var showLeftPanelButton: Bool
public var showRightPanelButton: Bool
public var backButton: NavigationItemButtonModel?
public var additionalLeftButtons: [NavigationItemButtonModel]?
public var additionalRightButtons: [NavigationItemButtonModel]?
// Legacy, will remove once menu is gone.
public var showLeftPanelButton: Bool
public var showRightPanelButton: Bool
public init() {
hidden = false
translucent = false

View File

@ -36,7 +36,7 @@ open class Carousel: View {
open var numberOfPages = 0
/// The models for the molecules.
var molecules: [MoleculeModelProtocol]?
var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]?
/// The horizontal alignment of the cell in the collection view. Only noticeable if the itemWidthPercent is less than 100%.
public var itemAlignment = UICollectionView.ScrollPosition.left
@ -176,11 +176,9 @@ open class Carousel: View {
if carouselModel?.loop ?? false && newMolecules.count > 1 {
// Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell).
loop = true
molecules?.insert(newMolecules.last!, at: 0)
molecules?.insert(newMolecules[(newMolecules.count - 2)], at: 0)
molecules?.append(newMolecules.first!)
molecules?.append(newMolecules[1])
molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0)
molecules?.append(contentsOf: newMolecules.prefix(2))
}
pageIndex = 0
@ -259,15 +257,15 @@ open class Carousel: View {
let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row }
if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex {
(collectionView.cellForItem(at: firstItem) as? CarouselItem)?.setPeaking(true, animated: true)
(collectionView.cellForItem(at: firstItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true)
}
if let lastItem = visibleItemsPaths.last, lastItem.row != currentIndex {
(collectionView.cellForItem(at: lastItem) as? CarouselItem)?.setPeaking(true, animated: true)
(collectionView.cellForItem(at: lastItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true)
}
} else {
// Hide peaking.
for item in collectionView.visibleCells {
(item as? CarouselItem)?.setPeaking(false, animated: true)
(item as? CarouselItemProtocol)?.setPeaking(false, animated: true)
}
}
}
@ -301,7 +299,7 @@ extension Carousel: UICollectionViewDelegateFlowLayout {
}
open func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? CarouselItem)?.setPeaking(false, animated: false)
(cell as? CarouselItemProtocol)?.setPeaking(false, animated: false)
}
}

View File

@ -19,7 +19,7 @@ import UIKit
}
public var backgroundColor: Color?
public var molecules: [CarouselItemModel]
public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]
public var index: Int = 0
public var spacing: Float?
public var border: Bool?
@ -29,7 +29,7 @@ import UIKit
public var itemAlignment: UICollectionView.ScrollPosition?
public var pagingMolecule: (CarouselPagingModelProtocol & MoleculeModelProtocol)?
public init(molecules: [CarouselItemModel]) {
public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) {
self.molecules = molecules
}
@ -57,7 +57,7 @@ import UIKit
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecules = try typeContainer.decode([CarouselItemModel].self, forKey: .molecules)
molecules = try typeContainer.decodeModels(codingKey: .molecules)
index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
spacing = try typeContainer.decodeIfPresent(Float.self, forKey: .spacing)
@ -73,7 +73,7 @@ import UIKit
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(molecules, forKey: .molecules)
try container.encodeModels(molecules, forKey: .molecules)
try container.encode(spacing, forKey: .spacing)
try container.encode(border, forKey: .border)
try container.encode(loop, forKey: .loop)

View File

@ -9,7 +9,5 @@
import Foundation
public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
var peakingUI: Bool? { get }
var peakingArrowColor: Color? { get }
public protocol CarouselItemModelProtocol: ContainerModelProtocol {
}

View File

@ -0,0 +1,15 @@
//
// CarouselItemProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/20/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol CarouselItemProtocol: UICollectionViewCell {
/// Notifies the cell if it is peaking or not.
func setPeaking(_ peaking: Bool, animated: Bool)
}

View File

@ -0,0 +1,21 @@
//
// NavigationItemModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/18/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol NavigationItemModelProtocol {
var title: String? { get set }
var hidden: Bool { get set }
var backgroundColor: Color? { get set }
var translucent: Bool { get set }
var tintColor: Color { get set }
var line: LineModel? { get set }
var backButton: NavigationItemButtonModel? { get set }
var additionalLeftButtons: [NavigationItemButtonModel]? { get set }
var additionalRightButtons: [NavigationItemButtonModel]? { get set }
}

View File

@ -0,0 +1,14 @@
//
// PanelNavigationItemModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/18/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol PanelNavigationItemModelProtocol {
var showLeftPanelButton: Bool { get set }
var showRightPanelButton: Bool { get set }
}

View File

@ -0,0 +1,82 @@
//
// BarButtonItem.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/18/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
public typealias BarButtonAction = (BarButtonItem) -> ()
@objc fileprivate class ActionDelegate: NSObject {
fileprivate var buttonAction: BarButtonAction?
@objc fileprivate func callActionBlock(_ sender: BarButtonItem) {
buttonAction?(sender)
}
}
@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol {
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
open weak var buttonDelegate: ButtonDelegateProtocol?
private var actionDelegate: ActionDelegate?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public static func create(with image: UIImage?) -> Self {
let actionObject = ActionDelegate()
let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:)))
button.actionDelegate = actionObject
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action map.
public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self {
let button = create(with: image)
button.actionDelegate?.buttonAction = action
return button
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
buttonDelegate = delegateObject?.buttonDelegate
actionDelegate?.buttonAction = { sender in
if let data = try? actionModel.encode(using: JSONEncoder()),
let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any],
delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
}
}
open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
buttonDelegate = delegateObject?.buttonDelegate
actionDelegate?.buttonAction = { sender in
guard delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return }
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
}
}

View File

@ -5,6 +5,7 @@
// Created by Scott Pfeil on 3/16/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
// A convenience aggregate for common MVM templates.
import Foundation

View File

@ -158,18 +158,27 @@ import UIKit
needsUpdateUI = true
view.setNeedsLayout()
}
/// 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.
var navigationModel = pageModel?.navigationItem ?? NavigationItemModel()
/// Creates a legacy navigation model.
open func createDefaultLegacyNavigationModel() -> NavigationItemModel {
let navigationModel = NavigationItemModel()
navigationModel.title = pageModel?.screenHeading
navigationModel.showLeftPanelButton = isMasterInitiallyAccessible()
navigationModel.showRightPanelButton = isSupportInitiallyAccessible()
if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true {
navigationModel.line = LineModel(type: .none)
}
pageModel?.navigationItem = navigationModel
return navigationModel
}
/// 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?.navigationItem == nil {
let navigationItem = createDefaultLegacyNavigationModel()
pageModel?.navigationItem = navigationItem
}
if formValidator == nil {
let rules = pageModel?.formRules
formValidator = FormValidator(rules)

View File

@ -11,35 +11,61 @@ import UIKit
@objcMembers open class NavigationController: UINavigationController {
public var separatorView: Line?
/// Getter for the main navigation controller
public static func navigationController() -> Self? {
return MVMCoreActionUtility.initializerClassCheck(MVMCoreUISession.sharedGlobal()?.navigationController, classToVerify: self) as? Self
}
public static func style(_ navigationBar: UINavigationBar) {
/// Provides MVM styling to the navigation bar. Returns a reference to the line.
public static func style(_ navigationBar: UINavigationBar) -> Line {
UIColor.mfSetBackgroundColor(forNavigationBar: .white, navigationBar: navigationBar, transparent: false)
navigationBar.shadowImage = UIImage()
navigationBar.isOpaque = true
navigationBar.tintColor = .black
navigationBar.titleTextAttributes = [NSAttributedString.Key.font: MFStyler.fontBoldBodySmall(false)];
return Line(pinTo: navigationBar, edge: .bottom, useMargin: false)
}
/// Sets up the application with a navigation controller
public static func setupNavigationController() -> Self? {
let navigationController = self.init()
style(navigationController.navigationBar)
navigationController.separatorView = Line(pinTo: navigationController.navigationBar, edge: .bottom, useMargin: false)
navigationController.separatorView?.setStyle(.standard)
navigationController.separatorView = style(navigationController.navigationBar)
MVMCoreUISession.sharedGlobal()?.navigationController = navigationController
MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController
MVMCoreNavigationHandler.shared()?.navigationController = navigationController
return navigationController
}
/// Sets up the application with a navigation controller as the main container.
public static func setupNavigationControllerAsMainController() -> Self? {
guard let navigationController = setupNavigationController() else { return nil }
MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController)
return navigationController
}
/// 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 items: [UIBarButtonItem] = []
if let backButtonModel = navigationItemModel.backButton,
navigationController.viewControllers.count > 1 {
items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
if let leftItemModels = navigationItemModel.additionalLeftButtons {
for item in leftItemModels {
items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
viewController.navigationItem.leftBarButtonItems = items
}
if let rightItemModels = navigationItemModel.additionalRightButtons {
for item in rightItemModels {
items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
viewController.navigationItem.rightBarButtonItems = items
}
}
/// Convenience function for setting navigation bar with model.
public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
viewController.navigationItem.title = navigationItemModel.title
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
@ -54,19 +80,26 @@ import UIKit
// Have the navigation title match the tint color
navigationController.navigationBar.titleTextAttributes?.updateValue(tint, forKey: .foregroundColor)
// Update icons if main navigation controller.
if navigationController == MVMCoreUISession.sharedGlobal()?.navigationController,
navigationController.topViewController == viewController {
// Update line.
MVMCoreUISession.sharedGlobal()?.navigationController?.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none
// Update line.
if let navigationController = navigationController as? NavigationController {
navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none
}
if navigationController == MVMCoreUISplitViewController.main()?.navigationController,
navigationController.topViewController == viewController {
// Update Panels
MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(navigationItemModel.showLeftPanelButton , for: viewController)
MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(navigationItemModel.showRightPanelButton , for: viewController)
MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint)
// Let legacy splitview controller handle buttons for now.
guard navigationController == MVMCoreUISplitViewController.main()?.navigationController,
navigationController.topViewController == viewController else {
// Not the main split view controller, add buttons.
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
}
// Update icons if main navigation controller.
MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint)
// Update Panels
if let model = navigationItemModel as? PanelNavigationItemModelProtocol {
MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController)
MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController)
}
}
}

View File

@ -124,8 +124,8 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
- (nullable UIImage *)imageForBackButton;
// Can overide to provide other global buttons to be on the navigation bar.
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtons;
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtons;
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController;
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController;
// The width of the panel when it is permanently extended. Default 320.
- (CGFloat)leftPanelExtendedWidth;

View File

@ -12,6 +12,7 @@
@import MVMCore.MVMCoreViewManagerProtocol;
@import MVMCore.MVMCoreObject;
@import MVMCore.MVMCoreActionUtility;
@import MVMCore.NSDictionary_MFConvenience;
#import "MVMCoreUIUtility.h"
#import "UIColor+MFConvenience.h"
#import "NSLayoutConstraint+MFConvenience.h"
@ -106,12 +107,29 @@ CGFloat const PanelAnimationDuration = 0.2;
return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer));
}
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtons {
return nil;
- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]];
if (!item) { return self.backButton; }
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
}
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtons {
return nil;
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]];
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
}
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]];
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
}
- (CGFloat)leftPanelExtendedWidth {
@ -234,12 +252,18 @@ CGFloat const PanelAnimationDuration = 0.2;
- (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended {
NSMutableArray *leftBarButtonItems = [NSMutableArray array];
if ([viewController.navigationController.viewControllers count] > 1) {
[leftBarButtonItems addObject:self.backButton];
UIBarButtonItem *button = [self getBackButtonForViewController:viewController];
if (button) {
viewController.navigationItem.hidesBackButton = YES;
[leftBarButtonItems addObject:button];
} else {
viewController.navigationItem.hidesBackButton = NO;
}
}
if ((accessible && !extended) && self.leftPanelButton) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
NSArray *extraButtons = [self additionalLeftButtons];
NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController];
if (extraButtons) {
[leftBarButtonItems addObjectsFromArray:extraButtons];
}
@ -410,7 +434,7 @@ CGFloat const PanelAnimationDuration = 0.2;
if ((accessible && !extended) && self.rightPanelButton) {
[navigationItems addObject:self.rightPanelButton];
}
NSArray *extraButtons = [self additionalRightButtons];
NSArray *extraButtons = [self additionalRightButtonsForViewController:viewController];
if (extraButtons) {
[navigationItems addObjectsFromArray:extraButtons];
}
@ -601,6 +625,24 @@ CGFloat const PanelAnimationDuration = 0.2;
#pragma mark - Other Panel Functions
/// Convenience function, creates a BarButtonItem from button json
- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil];
BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil];
return item;
}
/// Convenience function, creates a list of BarButtonItems list of json
- (nullable NSArray <UIBarButtonItem *>*)createNavigationItemButtonsFrom:(nullable NSArray <NSDictionary *>*)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
if (JSONlist.count == 0) { return nil; }
NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count];
for (NSDictionary *itemData in JSONlist) {
UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject];
[items addObject:item];
}
return items;
}
- (void)forceHideBothDrawers {
[self hideBothDrawersShouldForceHide:YES];
}