From fbc6e83038118ed29faa51a67ef52875e6a607e7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 20 Dec 2019 13:27:22 -0500 Subject: [PATCH 01/16] Created Protocol to centralize tap detection logic. --- MVMCoreUI.xcodeproj/project.pbxproj | 12 +++++++ MVMCoreUI/BaseClasses/Control.swift | 16 ++++------ .../Protocols/AppleGuidelinesProtocol.swift | 32 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c26f4c..2150daf1 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; + 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; @@ -226,6 +227,7 @@ 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; + 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = ""; }; 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = ""; }; @@ -438,6 +440,14 @@ path = FormUIHelpers; sourceTree = ""; }; + 0A5D59C323AD488600EFD9E9 /* Protocols */ = { + isa = PBXGroup; + children = ( + 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */, + ); + path = Protocols; + sourceTree = ""; + }; D213347423842FE3008E41B3 /* Controllers */ = { isa = PBXGroup; children = ( @@ -910,6 +920,7 @@ children = ( D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, + 0A5D59C323AD488600EFD9E9 /* Protocols */, ); path = BaseClasses; sourceTree = ""; @@ -1072,6 +1083,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */, D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index 5774ff5a..0b03ba27 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -47,18 +47,14 @@ import UIKit setupView() } } - - //-------------------------------------------------- - // MARK: - UITouch - //-------------------------------------------------- - +} + +// MARK: - AppleGuidelinesProtocol +extension Control: AppleGuidelinesProtocol { + override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - // If the control is smaller than 44pt by width or height, this will compensate. - let faultToleranceX: CGFloat = max((MinimumTappableArea - bounds.size.width) / 2.0, 0) - let faultToleranceY: CGFloat = max((MinimumTappableArea - bounds.size.height) / 2.0, 0) - let area = bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY) - return area.contains(point) + return Self.acceptablyOutsideBounds(point: point, bounds: bounds) } } diff --git a/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift b/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift new file mode 100644 index 00000000..3498a274 --- /dev/null +++ b/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift @@ -0,0 +1,32 @@ +// +// AppleGuidelinesProtocol.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 12/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + + +public protocol AppleGuidelinesProtocol { + static var minimumTappableArea: CGFloat { get } + static func acceptablyOutsideBounds(point: CGPoint, bounds: CGRect) -> Bool +} + +extension AppleGuidelinesProtocol { + + static public var minimumTappableArea: CGFloat { + return 44.0 + } + + // If the control is smaller than 44pt by width or height, this will compensate. + static public func acceptablyOutsideBounds(point: CGPoint, bounds: CGRect) -> Bool { + + let faultToleranceX: CGFloat = max((minimumTappableArea - bounds.size.width) / 2.0, 0) + let faultToleranceY: CGFloat = max((minimumTappableArea - bounds.size.height) / 2.0, 0) + let area = bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY) + + return area.contains(point) + } +} From 1d843ae29a6c2eafcaf5227ef4f97d2e3009fbb9 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Thu, 26 Dec 2019 19:33:37 +0530 Subject: [PATCH 02/16] main thread update access modifier update --- MVMCoreUI/Molecules/MFTextFieldListView.swift | 24 ++++++++++++++----- .../TextFieldListFormViewController.swift | 14 +++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift index 6d24e19a..6655cf01 100644 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ b/MVMCoreUI/Molecules/MFTextFieldListView.swift @@ -46,7 +46,7 @@ public class MFTextFieldListView: ViewConstrainingView { var viewList: [UIView] = [] for textFieldMap in textFieldMapList { - if let textField = MFTextField(map: textFieldMap, bothDelegates: self) { + if let textField = getTextFieldForMap(textFieldMap) { if textFieldMap.boolForKey("required") { textFieldsToValidate.append(textField) @@ -76,13 +76,25 @@ public class MFTextFieldListView: ViewConstrainingView { } public func getTextParamsList() -> [String: Any] { - var extraParam: [String: Any] = [:] - for textField in textFields { - if let fieldKey = textField.fieldKey { - extraParam[fieldKey as String] = textField.text ?? "" + return DispatchQueue.main.sync { + var extraParam: [String: Any] = [:] + for textField in textFields { + if let fieldKey = textField.fieldKey { + extraParam[fieldKey as String] = textField.text ?? "" + } } + return extraParam } - return extraParam + } + + private func getTextFieldForMap(_ map: [String: Any]) -> MFTextField? { + if map.boolForKey("dropDown") { + let dropDownFld = DropDown(map: map, bothDelegates: self) + dropDownFld?.setWithJSON(map, delegateObject: parentViewContoller?.delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) + dropDownFld?.showDropDown(true) + return dropDownFld + } + return MFTextField(map: map, bothDelegates: self) } } diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift index bf3b0bea..6aa3eec7 100644 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ b/MVMCoreUI/Templates/TextFieldListFormViewController.swift @@ -8,26 +8,26 @@ import UIKit -public class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { +open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { public var textFieldListView: MFTextFieldListView? - public override func viewDidLoad() { + open override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } - public override func updateViews() { + open override func updateViews() { super.updateViews() } - public override func newDataBuildScreen() { + open override func newDataBuildScreen() { super.newDataBuildScreen() topLabelsView?.separatorView?.isHidden = true } - public override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { + open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { var viewList: [UIView] = [] if let textFieldsList = loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] { @@ -40,12 +40,12 @@ public class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewContr return viewList } - public override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { + open override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { textFieldListView?.addParams(requestParameters: requestParameters) super.handleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData) } - public override func spaceAboveBetweenView() -> NSNumber? { + open override func spaceAboveBetweenView() -> NSNumber? { return PaddingFour as NSNumber } From ccc535360c2a690ff48012f2bed7c3252b25f2d3 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 27 Dec 2019 13:02:13 +0530 Subject: [PATCH 03/16] protocol implementation --- MVMCoreUI/Molecules/MFTextFieldListView.swift | 8 ++++++++ .../TextFieldListFormViewController.swift | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift index 6655cf01..c695c3a3 100644 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ b/MVMCoreUI/Molecules/MFTextFieldListView.swift @@ -9,6 +9,10 @@ import UIKit import MVMCore +@objc public protocol TextFieldListHelperProtocol { + @objc optional func fieldForMap(_ map: [String: Any], textField: MFTextField) + @objc optional func spaceBetweenField() -> CGFloat +} public class MFTextFieldListView: ViewConstrainingView { @@ -48,6 +52,8 @@ public class MFTextFieldListView: ViewConstrainingView { for textFieldMap in textFieldMapList { if let textField = getTextFieldForMap(textFieldMap) { + (parentViewContoller as? TextFieldListHelperProtocol)?.fieldForMap?(textFieldMap, textField: textField) + if textFieldMap.boolForKey("required") { textFieldsToValidate.append(textField) } @@ -60,11 +66,13 @@ public class MFTextFieldListView: ViewConstrainingView { } } + let spaceBtwField = (parentViewContoller as? TextFieldListHelperProtocol)?.spaceBetweenField?() ?? 0.0 StackableViewController.populateView(self, withUIArray: viewList) { (viewObject) -> UIEdgeInsets in var edgeInsets = StackableViewController.standardSpaceAroundUIObject() edgeInsets.left = 0 edgeInsets.right = 0 edgeInsets.top = 0 + edgeInsets.bottom = spaceBtwField return edgeInsets } diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift index 6aa3eec7..c0509679 100644 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ b/MVMCoreUI/Templates/TextFieldListFormViewController.swift @@ -8,7 +8,7 @@ import UIKit -open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { +open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController, TextFieldListHelperProtocol { public var textFieldListView: MFTextFieldListView? @@ -30,7 +30,7 @@ open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewControl open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { var viewList: [UIView] = [] - if let textFieldsList = loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] { + if let textFieldsList = textFieldsLists() { let textFieldListView = MFTextFieldListView(textFieldMapList: textFieldsList, parentViewContoller: self, primaryButton: self.primaryButton) @@ -48,5 +48,18 @@ open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewControl open override func spaceAboveBetweenView() -> NSNumber? { return PaddingFour as NSNumber } + + open func textFieldsLists() -> [[String: Any]]? { + return loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] + } + + //MARK: - Textfield list protocol + open func spaceBetweenField() -> CGFloat { + return 0.0 + } + + open func fieldForMap(_ map: [String : Any], textField: MFTextField) { + + } } From e5ca7b5c9e2996091496750180a871843d3cbf97 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Thu, 2 Jan 2020 21:33:31 +0530 Subject: [PATCH 04/16] bullet list molecule added --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Molecules/BulletList.swift | 233 ++++++++++++++++++ .../MVMCoreUIMoleculeMappingObject.m | 3 +- 3 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Molecules/BulletList.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c26f4c..14506f07 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63D632023BDC3A0008F3B1F /* BulletList.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -233,6 +234,7 @@ 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + C63D632023BDC3A0008F3B1F /* BulletList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulletList.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -633,6 +635,7 @@ 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, + C63D632023BDC3A0008F3B1F /* BulletList.swift */, ); path = Molecules; sourceTree = ""; @@ -1177,6 +1180,7 @@ 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, + C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift new file mode 100644 index 00000000..f680b36a --- /dev/null +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -0,0 +1,233 @@ +// +// BulletList.swift +// MVMCoreUI +// +// Created by Murugan, Vimal on 02/01/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class BulletList: Container { + + var contentView = MVMCoreUICommonViewsUtility.commonView() + var reusableViews: [LeftRightLabelView] = [] + var bulletChar: String? + + /// Restacks the existing items. + func restack() { + //setWithStackItems(items) + } + + /// Removes all stack items views from the view. + func removeAllItemInViews() { + reusableViews.forEach({ $0.removeFromSuperview() }) + } + + /// The spacing to use between each item in the stack. + var verticalSpacing: CGFloat = 8 { + didSet { + if verticalSpacing != oldValue { + restack() + } + } + } + + // MARK: - Inits + public override init() { + super.init() + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.init(frame: CGRect.zero) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Helpers + public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { + let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) + constraint.priority = priority + constraint.isActive = true + } + + // MARK: - MFViewProtocol + public override func setupView() { + super.setupView() + guard contentView.superview == nil else { + return + } + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) + translatesAutoresizingMaskIntoConstraints = false + backgroundColor = .clear + addSubview(contentView) + containerHelper.constrainView(contentView) + contentView.setContentHuggingPriority(.defaultHigh, for: .vertical) + contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal) + } + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + directionalLayoutMargins.leading = 0 + directionalLayoutMargins.trailing = 0 + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + public override func reset() { + super.reset() + backgroundColor = .clear + } + + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + // let previousJSON = self.json + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + removeAllItemInViews() + guard let list = json?.arrayForKey("list") as? [[String: Any]] else { + return + } + + bulletChar = json?.optionalStringForKey("bulletChar") + + var views = [LeftLabelRightContainer]() + // Adds the molecules and sets the json. + for (index, map) in list.enumerated() { + let view = LeftLabelRightContainer() + let moleculeMap = ["left": leftItem(bulletChar ?? String(index + 1)), "right": map] + view.setWithJSON(moleculeMap, delegateObject: delegateObject, additionalData: additionalData) + views.append(view) + } + let lastObj = views.last + MVMCoreUIStackableViewController.populateView(contentView, withUIArray: views) { (obj) -> UIEdgeInsets in + return UIEdgeInsets(top: 0, left: 0, bottom: lastObj?.isEqual(obj) ?? false ? 0 : 16, right: 0) + } + } + + public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { + // This will aggregate names of molecules to make an id. + guard let molecules = molecule?.optionalArrayForKey("list") else { + return "stack<>" + } + var name = "stack<" + for case let item as [AnyHashable: Any] in molecules { + if let molecule = item.optionalDictionaryForKey(KeyMolecule), let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) { + name.append(moleculeName + ",") + } + } + name.append(">") + return name + } + + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + guard let items = json?.optionalArrayForKey("list") else { + return nil + } + var modules: [String] = [] + for case let item as [AnyHashable: AnyHashable] in items { + if let molecule = item.optionalDictionaryForKey(KeyMolecule), let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.requiredModules?(molecule, delegateObject: delegateObject, error: error) { + modules += modulesForMolecule + } + } + return modules.count > 0 ? modules : nil + } + + func leftItem(_ string: String) -> [String: Any] { + return ["moleculeName":"label","text":string, "fontStyle":"B2"] + } + +} + +class LeftLabelRightContainer: View { + + var label = Label.commonLabelB2(true) + var rightContainer = MVMCoreUICommonViewsUtility.commonView() + var leftContainer = MVMCoreUICommonViewsUtility.commonView() + var rightMoleculeName: String? + var rightMolecule: View? + let containerHelper = ContainerHelper() + + var constraintBtwViews: NSLayoutConstraint? + var spaceBtwViews: CGFloat = 8 { + didSet { + if spaceBtwViews != oldValue { + constraintBtwViews?.constant = spaceBtwViews + layoutIfNeeded() + } + } + } + + override func setupView() { + super.setupView() + + guard rightContainer.superview == nil else { + return + } + + translatesAutoresizingMaskIntoConstraints = false + addSubview(rightContainer) + addSubview(leftContainer) + leftContainer.addSubview(label) + NSLayoutConstraint.constraintPinSubview(toSuperview: label) + + NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) + bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true + + NSLayoutConstraint.constraintPinSubview(rightContainer, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) + constraintBtwViews = rightContainer.leftAnchor.constraint(equalTo: leftContainer.rightAnchor, constant: spaceBtwViews) + constraintBtwViews?.priority = .required + constraintBtwViews?.isActive = true + + //TODO: Need to get confirmation on this + leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true + setContentHuggingPriority(.defaultHigh, for: .vertical) + setContentHuggingPriority(.defaultHigh, for: .horizontal) + rightContainer.setContentHuggingPriority(.defaultHigh, for: .vertical) + rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) + + label.setContentHuggingPriority(.defaultHigh, for: .horizontal) + label.setContentHuggingPriority(.defaultHigh, for: .vertical) + + } + + override func updateView(_ size: CGFloat) { + super.updateView(size) + } + + override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + let previousMoleculeName = rightMoleculeName + guard let moleculeJSON = json?.optionalDictionaryForKey("right") else { + removeSubviewsInRightContainer() + return + } + + Label.setUILabel(label, withJSON: json?.optionalDictionaryForKey("left"), delegate: delegateObject, additionalData: additionalData) + rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) + //For reuse purpose check that allready added molecule is same + if rightMolecule != nil && previousMoleculeName == rightMoleculeName { + rightMolecule?.setWithJSON(json?.optionalDictionaryForKey("right"), delegateObject: delegateObject, additionalData: additionalData) + } else { + removeSubviewsInRightContainer() + if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { + addView(molecule) + } + } + } + + func removeSubviewsInRightContainer() { + rightContainer.subviews.forEach({ $0.removeFromSuperview() }) + } + + func addView(_ view: UIView) { + view.translatesAutoresizingMaskIntoConstraints = false + rightContainer.addSubview(view) + containerHelper.constrainView(view) + rightMolecule = view as? View + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 9db7822d..47bbac98 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -66,7 +66,8 @@ @"tabsListItem": TabsTableViewCell.class, @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, - @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class + @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class, + @"bulletList": BulletList.class } mutableCopy]; }); return mapping; From c4fbf578907a066d7d50f4460248f933d4fdc256 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 3 Jan 2020 19:52:10 +0530 Subject: [PATCH 05/16] MOBFIRST-19249 : List Item Style Updates Adding shortDivider and tallDivider style. Removing header style. --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index 9cf77ae1..f1fb3519 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -47,8 +47,10 @@ import UIKit switch styleString { case "standard": styleStandard() - case "header": - styleHeader() + case "shortDivider": + styleShortDivider() + case "tallDivider": + styleTallDivider() case "sectionFooter": styleFooter() case "none": @@ -64,11 +66,18 @@ import UIKit bottomSeparatorView?.style = .standard } - open func styleHeader() { + open func styleTallDivider() { topMarginPadding = 48 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .thin + bottomSeparatorView?.style = .standard + } + + open func styleShortDivider() { + topMarginPadding = 32 + bottomMarginPadding = 16 + topSeparatorView?.style = .none + bottomSeparatorView?.style = .standard } open func styleFooter() { From dd49c439462e02321657788a566efca17190a792 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 3 Jan 2020 20:18:30 +0530 Subject: [PATCH 06/16] code cleanup --- MVMCoreUI/Molecules/BulletList.swift | 137 ++++++++++++++++++--------- 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift index f680b36a..5cb0dbd4 100644 --- a/MVMCoreUI/Molecules/BulletList.swift +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -11,28 +11,14 @@ import UIKit open class BulletList: Container { var contentView = MVMCoreUICommonViewsUtility.commonView() - var reusableViews: [LeftRightLabelView] = [] + var reusableViews: [LeftLabelRightMoleculeContainer] = [] var bulletChar: String? - /// Restacks the existing items. - func restack() { - //setWithStackItems(items) - } - /// Removes all stack items views from the view. func removeAllItemInViews() { reusableViews.forEach({ $0.removeFromSuperview() }) } - /// The spacing to use between each item in the stack. - var verticalSpacing: CGFloat = 8 { - didSet { - if verticalSpacing != oldValue { - restack() - } - } - } - // MARK: - Inits public override init() { super.init() @@ -77,46 +63,72 @@ open class BulletList: Container { super.updateView(size) directionalLayoutMargins.leading = 0 directionalLayoutMargins.trailing = 0 + reusableViews.forEach({ $0.updateView(size) }) } // MARK: - MVMCoreUIMoleculeViewProtocol public override func reset() { super.reset() backgroundColor = .clear + reusableViews.forEach({ $0.reset() }) } open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - // let previousJSON = self.json + let previousJSON = self.json super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) removeAllItemInViews() + // If the items in the stack are the same, just update previous items instead of re-allocating. + var items: [LeftLabelRightMoleculeContainer]? + if BulletList.name(forReuse: previousJSON, delegateObject: delegateObject) == BulletList.name(forReuse: json, delegateObject: delegateObject) { + items = self.reusableViews + } + self.reusableViews = [] + guard let list = json?.arrayForKey("list") as? [[String: Any]] else { return } bulletChar = json?.optionalStringForKey("bulletChar") - - var views = [LeftLabelRightContainer]() // Adds the molecules and sets the json. for (index, map) in list.enumerated() { - let view = LeftLabelRightContainer() - let moleculeMap = ["left": leftItem(bulletChar ?? String(index + 1)), "right": map] - view.setWithJSON(moleculeMap, delegateObject: delegateObject, additionalData: additionalData) - views.append(view) + if let item = items?[index] { + item.leftText = bulletChar + item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) + addView(item, lastItem: index == list.count - 1) + } else { + let leftLabel = LeftLabelRightMoleculeContainer() + leftLabel.leftText = bulletChar + leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) + addView(leftLabel, lastItem: index == list.count - 1) + } } - let lastObj = views.last - MVMCoreUIStackableViewController.populateView(contentView, withUIArray: views) { (obj) -> UIEdgeInsets in - return UIEdgeInsets(top: 0, left: 0, bottom: lastObj?.isEqual(obj) ?? false ? 0 : 16, right: 0) + } + + func addView(_ container: LeftLabelRightMoleculeContainer, lastItem: Bool) { + container.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(container) + let first = reusableViews.first == nil + if first { + pinView(container, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 16) + } else if let previousView = reusableViews.last { + container.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: 16).isActive = true } + pinView(container, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) + pinView(contentView, toView: container, attribute: .trailing, relation: .equal, priority: .required, constant: 0) + if lastItem { + pinView(contentView, toView: container, attribute: .bottom, relation: .equal, priority: .required, constant: 0) + } + reusableViews.append(container) } public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { // This will aggregate names of molecules to make an id. guard let molecules = molecule?.optionalArrayForKey("list") else { - return "stack<>" + return "unordered<>" } - var name = "stack<" + var name = "unordered<" for case let item as [AnyHashable: Any] in molecules { - if let molecule = item.optionalDictionaryForKey(KeyMolecule), let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) { + if let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? item.optionalStringForKey(KeyMoleculeName) { name.append(moleculeName + ",") } } @@ -124,26 +136,36 @@ open class BulletList: Container { return name } + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + guard let items = json?.optionalArrayForKey("list") else { + return 0 + } + var estimatedHeight: CGFloat = 0 + for case let item as [AnyHashable: AnyHashable] in items { + if let _ = item.optionalStringForKey(KeyMoleculeName) { + let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.estimatedHeight?(forRow: item, delegateObject: delegateObject) + estimatedHeight += ((height ?? 0) + 16) + } + } + return estimatedHeight + } + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { guard let items = json?.optionalArrayForKey("list") else { return nil } var modules: [String] = [] for case let item as [AnyHashable: AnyHashable] in items { - if let molecule = item.optionalDictionaryForKey(KeyMolecule), let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.requiredModules?(molecule, delegateObject: delegateObject, error: error) { + if let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.requiredModules?(item, delegateObject: delegateObject, error: error) { modules += modulesForMolecule } } return modules.count > 0 ? modules : nil } - - func leftItem(_ string: String) -> [String: Any] { - return ["moleculeName":"label","text":string, "fontStyle":"B2"] - } } -class LeftLabelRightContainer: View { +class LeftLabelRightMoleculeContainer: View { var label = Label.commonLabelB2(true) var rightContainer = MVMCoreUICommonViewsUtility.commonView() @@ -151,6 +173,7 @@ class LeftLabelRightContainer: View { var rightMoleculeName: String? var rightMolecule: View? let containerHelper = ContainerHelper() + var leftText: String? var constraintBtwViews: NSLayoutConstraint? var spaceBtwViews: CGFloat = 8 { @@ -162,6 +185,24 @@ class LeftLabelRightContainer: View { } } + // MARK: - Inits + public override init() { + super.init() + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.init(frame: CGRect.zero) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func setupView() { super.setupView() @@ -173,7 +214,9 @@ class LeftLabelRightContainer: View { addSubview(rightContainer) addSubview(leftContainer) leftContainer.addSubview(label) - NSLayoutConstraint.constraintPinSubview(toSuperview: label) + //NSLayoutConstraint.constraintPinSubview(toSuperview: label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) + leftContainer.leftAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor).isActive = true NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true @@ -184,10 +227,10 @@ class LeftLabelRightContainer: View { constraintBtwViews?.isActive = true //TODO: Need to get confirmation on this - leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true + //leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true setContentHuggingPriority(.defaultHigh, for: .vertical) setContentHuggingPriority(.defaultHigh, for: .horizontal) - rightContainer.setContentHuggingPriority(.defaultHigh, for: .vertical) + rightContainer.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) label.setContentHuggingPriority(.defaultHigh, for: .horizontal) @@ -197,23 +240,31 @@ class LeftLabelRightContainer: View { override func updateView(_ size: CGFloat) { super.updateView(size) + rightMolecule?.updateView(size) + label.updateView(size) + } + + override func reset() { + super.reset() + rightMolecule?.reset() } override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) let previousMoleculeName = rightMoleculeName - guard let moleculeJSON = json?.optionalDictionaryForKey("right") else { - removeSubviewsInRightContainer() + removeSubviewsInRightContainer() + guard let moleculeJSON = json, let _ = moleculeJSON.optionalStringForKey(KeyMoleculeName) else { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) return } - Label.setUILabel(label, withJSON: json?.optionalDictionaryForKey("left"), delegate: delegateObject, additionalData: additionalData) + label.text = leftText rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) //For reuse purpose check that allready added molecule is same - if rightMolecule != nil && previousMoleculeName == rightMoleculeName { - rightMolecule?.setWithJSON(json?.optionalDictionaryForKey("right"), delegateObject: delegateObject, additionalData: additionalData) + if let rightMolecule = self.rightMolecule, previousMoleculeName == rightMoleculeName { + rightMolecule.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) + addView(rightMolecule) } else { - removeSubviewsInRightContainer() if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { addView(molecule) } From 709277362f6a5a7bc6076d2b6a49a8674a95484e Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 3 Jan 2020 20:20:23 +0530 Subject: [PATCH 07/16] updated constraints --- MVMCoreUI/Molecules/BulletList.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift index 5cb0dbd4..e5eab994 100644 --- a/MVMCoreUI/Molecules/BulletList.swift +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -92,12 +92,12 @@ open class BulletList: Container { // Adds the molecules and sets the json. for (index, map) in list.enumerated() { if let item = items?[index] { - item.leftText = bulletChar + item.leftText = bulletChar ?? String(index+1) item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) addView(item, lastItem: index == list.count - 1) } else { let leftLabel = LeftLabelRightMoleculeContainer() - leftLabel.leftText = bulletChar + leftLabel.leftText = bulletChar ?? String(index+1) leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) addView(leftLabel, lastItem: index == list.count - 1) } @@ -214,9 +214,16 @@ class LeftLabelRightMoleculeContainer: View { addSubview(rightContainer) addSubview(leftContainer) leftContainer.addSubview(label) - //NSLayoutConstraint.constraintPinSubview(toSuperview: label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - leftContainer.leftAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor).isActive = true + label.rightAnchor.constraint(greaterThanOrEqualTo: leftContainer.leftAnchor).isActive = true + let labelRightAnchor = label.rightAnchor.constraint(equalTo: leftContainer.leftAnchor) + labelRightAnchor.priority = UILayoutPriority(rawValue: 200) + labelRightAnchor.isActive = true + leftContainer.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true + let labelBotAnchor = leftContainer.bottomAnchor.constraint(equalTo: label.bottomAnchor) + labelBotAnchor.priority = UILayoutPriority(rawValue: 200) + labelBotAnchor.isActive = true NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true From f1f34b289307a4318f326010fd09cd8ab6ff65b5 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Sat, 4 Jan 2020 14:26:09 +0530 Subject: [PATCH 08/16] textfield list view and textfield list form controller been moved to mobilefirstframework --- MVMCoreUI.xcodeproj/project.pbxproj | 12 - MVMCoreUI/Molecules/BulletList.swift | 291 ------------------ MVMCoreUI/Molecules/MFTextFieldListView.swift | 143 --------- .../MVMCoreUIMoleculeMappingObject.m | 3 +- .../MVMCoreUIViewControllerMappingObject.m | 1 - .../TextFieldListFormViewController.swift | 65 ---- 6 files changed, 1 insertion(+), 514 deletions(-) delete mode 100644 MVMCoreUI/Molecules/BulletList.swift delete mode 100644 MVMCoreUI/Molecules/MFTextFieldListView.swift delete mode 100644 MVMCoreUI/Templates/TextFieldListFormViewController.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 14506f07..b33ce6e9 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -20,8 +20,6 @@ 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; - 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; }; - 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; }; 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */; }; @@ -32,7 +30,6 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; - C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63D632023BDC3A0008F3B1F /* BulletList.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -223,8 +220,6 @@ 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; - 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = ""; }; - 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; @@ -234,7 +229,6 @@ 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; - C63D632023BDC3A0008F3B1F /* BulletList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulletList.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -586,7 +580,6 @@ D29DF0DF21E418B2003B2FB9 /* Templates */ = { isa = PBXGroup; children = ( - 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */, D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */, D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */, D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */, @@ -624,7 +617,6 @@ D224798D2316A988003FCCF9 /* VerticalCombinationViews */, D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, - 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, D2A514662213885800345BFB /* StandardHeaderView.swift */, @@ -635,7 +627,6 @@ 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, - C63D632023BDC3A0008F3B1F /* BulletList.swift */, ); path = Molecules; sourceTree = ""; @@ -1105,7 +1096,6 @@ D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */, - 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */, D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */, D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */, @@ -1141,7 +1131,6 @@ D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, - 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, @@ -1180,7 +1169,6 @@ 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, - C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift deleted file mode 100644 index e5eab994..00000000 --- a/MVMCoreUI/Molecules/BulletList.swift +++ /dev/null @@ -1,291 +0,0 @@ -// -// BulletList.swift -// MVMCoreUI -// -// Created by Murugan, Vimal on 02/01/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - -open class BulletList: Container { - - var contentView = MVMCoreUICommonViewsUtility.commonView() - var reusableViews: [LeftLabelRightMoleculeContainer] = [] - var bulletChar: String? - - /// Removes all stack items views from the view. - func removeAllItemInViews() { - reusableViews.forEach({ $0.removeFromSuperview() }) - } - - // MARK: - Inits - public override init() { - super.init() - } - - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.init(frame: CGRect.zero) - setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // MARK: - Helpers - public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { - let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) - constraint.priority = priority - constraint.isActive = true - } - - // MARK: - MFViewProtocol - public override func setupView() { - super.setupView() - guard contentView.superview == nil else { - return - } - MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) - translatesAutoresizingMaskIntoConstraints = false - backgroundColor = .clear - addSubview(contentView) - containerHelper.constrainView(contentView) - contentView.setContentHuggingPriority(.defaultHigh, for: .vertical) - contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal) - } - - public override func updateView(_ size: CGFloat) { - super.updateView(size) - directionalLayoutMargins.leading = 0 - directionalLayoutMargins.trailing = 0 - reusableViews.forEach({ $0.updateView(size) }) - } - - // MARK: - MVMCoreUIMoleculeViewProtocol - public override func reset() { - super.reset() - backgroundColor = .clear - reusableViews.forEach({ $0.reset() }) - } - - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - let previousJSON = self.json - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - removeAllItemInViews() - // If the items in the stack are the same, just update previous items instead of re-allocating. - var items: [LeftLabelRightMoleculeContainer]? - if BulletList.name(forReuse: previousJSON, delegateObject: delegateObject) == BulletList.name(forReuse: json, delegateObject: delegateObject) { - items = self.reusableViews - } - self.reusableViews = [] - - guard let list = json?.arrayForKey("list") as? [[String: Any]] else { - return - } - - bulletChar = json?.optionalStringForKey("bulletChar") - // Adds the molecules and sets the json. - for (index, map) in list.enumerated() { - if let item = items?[index] { - item.leftText = bulletChar ?? String(index+1) - item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) - addView(item, lastItem: index == list.count - 1) - } else { - let leftLabel = LeftLabelRightMoleculeContainer() - leftLabel.leftText = bulletChar ?? String(index+1) - leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) - addView(leftLabel, lastItem: index == list.count - 1) - } - } - } - - func addView(_ container: LeftLabelRightMoleculeContainer, lastItem: Bool) { - container.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(container) - let first = reusableViews.first == nil - if first { - pinView(container, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 16) - } else if let previousView = reusableViews.last { - container.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: 16).isActive = true - } - pinView(container, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) - pinView(contentView, toView: container, attribute: .trailing, relation: .equal, priority: .required, constant: 0) - if lastItem { - pinView(contentView, toView: container, attribute: .bottom, relation: .equal, priority: .required, constant: 0) - } - reusableViews.append(container) - } - - public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { - // This will aggregate names of molecules to make an id. - guard let molecules = molecule?.optionalArrayForKey("list") else { - return "unordered<>" - } - var name = "unordered<" - for case let item as [AnyHashable: Any] in molecules { - if let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? item.optionalStringForKey(KeyMoleculeName) { - name.append(moleculeName + ",") - } - } - name.append(">") - return name - } - - public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - guard let items = json?.optionalArrayForKey("list") else { - return 0 - } - var estimatedHeight: CGFloat = 0 - for case let item as [AnyHashable: AnyHashable] in items { - if let _ = item.optionalStringForKey(KeyMoleculeName) { - let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.estimatedHeight?(forRow: item, delegateObject: delegateObject) - estimatedHeight += ((height ?? 0) + 16) - } - } - return estimatedHeight - } - - public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let items = json?.optionalArrayForKey("list") else { - return nil - } - var modules: [String] = [] - for case let item as [AnyHashable: AnyHashable] in items { - if let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.requiredModules?(item, delegateObject: delegateObject, error: error) { - modules += modulesForMolecule - } - } - return modules.count > 0 ? modules : nil - } - -} - -class LeftLabelRightMoleculeContainer: View { - - var label = Label.commonLabelB2(true) - var rightContainer = MVMCoreUICommonViewsUtility.commonView() - var leftContainer = MVMCoreUICommonViewsUtility.commonView() - var rightMoleculeName: String? - var rightMolecule: View? - let containerHelper = ContainerHelper() - var leftText: String? - - var constraintBtwViews: NSLayoutConstraint? - var spaceBtwViews: CGFloat = 8 { - didSet { - if spaceBtwViews != oldValue { - constraintBtwViews?.constant = spaceBtwViews - layoutIfNeeded() - } - } - } - - // MARK: - Inits - public override init() { - super.init() - } - - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.init(frame: CGRect.zero) - setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func setupView() { - super.setupView() - - guard rightContainer.superview == nil else { - return - } - - translatesAutoresizingMaskIntoConstraints = false - addSubview(rightContainer) - addSubview(leftContainer) - leftContainer.addSubview(label) - - NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - label.rightAnchor.constraint(greaterThanOrEqualTo: leftContainer.leftAnchor).isActive = true - let labelRightAnchor = label.rightAnchor.constraint(equalTo: leftContainer.leftAnchor) - labelRightAnchor.priority = UILayoutPriority(rawValue: 200) - labelRightAnchor.isActive = true - leftContainer.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true - let labelBotAnchor = leftContainer.bottomAnchor.constraint(equalTo: label.bottomAnchor) - labelBotAnchor.priority = UILayoutPriority(rawValue: 200) - labelBotAnchor.isActive = true - - NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true - - NSLayoutConstraint.constraintPinSubview(rightContainer, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) - constraintBtwViews = rightContainer.leftAnchor.constraint(equalTo: leftContainer.rightAnchor, constant: spaceBtwViews) - constraintBtwViews?.priority = .required - constraintBtwViews?.isActive = true - - //TODO: Need to get confirmation on this - //leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true - setContentHuggingPriority(.defaultHigh, for: .vertical) - setContentHuggingPriority(.defaultHigh, for: .horizontal) - rightContainer.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) - rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) - - label.setContentHuggingPriority(.defaultHigh, for: .horizontal) - label.setContentHuggingPriority(.defaultHigh, for: .vertical) - - } - - override func updateView(_ size: CGFloat) { - super.updateView(size) - rightMolecule?.updateView(size) - label.updateView(size) - } - - override func reset() { - super.reset() - rightMolecule?.reset() - } - - override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - let previousMoleculeName = rightMoleculeName - removeSubviewsInRightContainer() - guard let moleculeJSON = json, let _ = moleculeJSON.optionalStringForKey(KeyMoleculeName) else { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - return - } - - label.text = leftText - rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) - //For reuse purpose check that allready added molecule is same - if let rightMolecule = self.rightMolecule, previousMoleculeName == rightMoleculeName { - rightMolecule.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) - addView(rightMolecule) - } else { - if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { - addView(molecule) - } - } - } - - func removeSubviewsInRightContainer() { - rightContainer.subviews.forEach({ $0.removeFromSuperview() }) - } - - func addView(_ view: UIView) { - view.translatesAutoresizingMaskIntoConstraints = false - rightContainer.addSubview(view) - containerHelper.constrainView(view) - rightMolecule = view as? View - } -} diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift deleted file mode 100644 index c695c3a3..00000000 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ /dev/null @@ -1,143 +0,0 @@ -// -// MFTextFieldListView.swift -// MobileFirstFramework -// -// Created by Suresh, Kamlesh on 9/21/18. -// Copyright © 2018 Verizon Wireless. All rights reserved. -// - -import UIKit -import MVMCore - -@objc public protocol TextFieldListHelperProtocol { - @objc optional func fieldForMap(_ map: [String: Any], textField: MFTextField) - @objc optional func spaceBetweenField() -> CGFloat -} - -public class MFTextFieldListView: ViewConstrainingView { - - public var textFieldMapList: [[String: Any]]? - public var parentViewContoller: MFViewController? - public var textFieldsToValidate: [MFTextField] = [] - public var textFields: [MFTextField] = [] - public var primaryButton: PrimaryButton? - - public init(textFieldMapList: [[String: Any]], parentViewContoller: MFViewController, primaryButton: PrimaryButton?) { - self.textFieldMapList = textFieldMapList - self.parentViewContoller = parentViewContoller - self.primaryButton = primaryButton - super.init(frame: .zero) - } - - public required init?(coder decoder: NSCoder) { - super.init(coder: decoder) - } - - public override func updateView(_ size: CGFloat) { - super.updateView(size) - for textField in textFields { - textField.updateView(size) - } - } - - public override func setupView() { - super.setupView() - self.translatesAutoresizingMaskIntoConstraints = false - - guard let textFieldMapList = textFieldMapList else { - return - } - var viewList: [UIView] = [] - - for textFieldMap in textFieldMapList { - if let textField = getTextFieldForMap(textFieldMap) { - - (parentViewContoller as? TextFieldListHelperProtocol)?.fieldForMap?(textFieldMap, textField: textField) - - if textFieldMap.boolForKey("required") { - textFieldsToValidate.append(textField) - } - - textFields.append(textField) - if let fieldKey = textField.fieldKey { - parentViewContoller?.register(textField, forErrorKey: fieldKey as String) - } - viewList.append(textField) - } - } - - let spaceBtwField = (parentViewContoller as? TextFieldListHelperProtocol)?.spaceBetweenField?() ?? 0.0 - StackableViewController.populateView(self, withUIArray: viewList) { (viewObject) -> UIEdgeInsets in - var edgeInsets = StackableViewController.standardSpaceAroundUIObject() - edgeInsets.left = 0 - edgeInsets.right = 0 - edgeInsets.top = 0 - edgeInsets.bottom = spaceBtwField - return edgeInsets - } - - primaryButton?.handleEnabling(with: textFieldsToValidate) - } - - public func addParams(requestParameters: MVMCoreRequestParameters) { - requestParameters.add(getTextParamsList()) - } - - public func getTextParamsList() -> [String: Any] { - return DispatchQueue.main.sync { - var extraParam: [String: Any] = [:] - for textField in textFields { - if let fieldKey = textField.fieldKey { - extraParam[fieldKey as String] = textField.text ?? "" - } - } - return extraParam - } - } - - private func getTextFieldForMap(_ map: [String: Any]) -> MFTextField? { - if map.boolForKey("dropDown") { - let dropDownFld = DropDown(map: map, bothDelegates: self) - dropDownFld?.setWithJSON(map, delegateObject: parentViewContoller?.delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) - dropDownFld?.showDropDown(true) - return dropDownFld - } - return MFTextField(map: map, bothDelegates: self) - } -} - -extension MFTextFieldListView: UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate { - @objc open func textFieldDidEndEditing(_ textField: UITextField) { - parentViewContoller?.textFieldDidEndEditing(textField) - primaryButton?.handleEnabling(with: textFieldsToValidate) - } - - @objc open func dismissFieldInput(_ sender: Any?) { - parentViewContoller?.dismissFieldInput(sender) - } - - @objc open func textFieldShouldReturn(_ textField: UITextField) -> Bool { - textField.resignFirstResponder() - return true - } - - @objc open func textFieldDidBeginEditing(_ textField: UITextField) { - parentViewContoller?.textFieldDidBeginEditing(textField) - } - - @objc open func entryIsValid(_ textfield: MFTextField?) { - DispatchQueue.main.async { - if self.parentViewContoller?.responds(to: #selector(MFTextFieldDelegate.entryIsValid(_:))) ?? false { - self.parentViewContoller?.entryIsValid(textfield) - } - } - } - - @objc open func entryIsInvalid(_ textfield: MFTextField?) { - DispatchQueue.main.async { - if self.parentViewContoller?.responds(to: #selector(MFTextFieldDelegate.entryIsInvalid(_:))) ?? false { - self.parentViewContoller?.entryIsInvalid(textfield) - } - } - } -} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 47bbac98..9db7822d 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -66,8 +66,7 @@ @"tabsListItem": TabsTableViewCell.class, @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, - @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class, - @"bulletList": BulletList.class + @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class } mutableCopy]; }); return mapping; diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index e770ede5..2bc1a0dd 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -19,7 +19,6 @@ static NSMutableDictionary *viewControllerMapping; dispatch_once(&onceToken, ^{ viewControllerMapping = [@{ - @"textFieldListForm" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[TextFieldListFormViewController class]], @"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift deleted file mode 100644 index c0509679..00000000 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// MVMCoreUITextFormViewController.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 1/24/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import UIKit - -open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController, TextFieldListHelperProtocol { - - - public var textFieldListView: MFTextFieldListView? - - open override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - open override func updateViews() { - super.updateViews() - } - - open override func newDataBuildScreen() { - super.newDataBuildScreen() - topLabelsView?.separatorView?.isHidden = true - } - - open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { - var viewList: [UIView] = [] - - if let textFieldsList = textFieldsLists() { - let textFieldListView = MFTextFieldListView(textFieldMapList: textFieldsList, - parentViewContoller: self, - primaryButton: self.primaryButton) - self.textFieldListView = textFieldListView - viewList.append(textFieldListView) - } - return viewList - } - - open override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { - textFieldListView?.addParams(requestParameters: requestParameters) - super.handleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData) - } - - open override func spaceAboveBetweenView() -> NSNumber? { - return PaddingFour as NSNumber - } - - open func textFieldsLists() -> [[String: Any]]? { - return loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] - } - - //MARK: - Textfield list protocol - open func spaceBetweenField() -> CGFloat { - return 0.0 - } - - open func fieldForMap(_ map: [String : Any], textField: MFTextField) { - - } - -} From bf0b2ecb79006741993e4b58ae75a033e0cdf864 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Mon, 6 Jan 2020 16:49:03 +0530 Subject: [PATCH 09/16] changed separator style to thin --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index f1fb3519..b1aa92a5 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -70,14 +70,14 @@ import UIKit topMarginPadding = 48 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .standard + bottomSeparatorView?.style = .thin } open func styleShortDivider() { topMarginPadding = 32 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .standard + bottomSeparatorView?.style = .thin } open func styleFooter() { From 2abd6a866a6502d98e31e30e64f7a0b171aa7ec9 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 8 Jan 2020 09:28:54 -0500 Subject: [PATCH 10/16] Explaining use case of Color. --- MVMCoreUI/Models/Primitive Models/Color.swift | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Models/Primitive Models/Color.swift b/MVMCoreUI/Models/Primitive Models/Color.swift index 027b826e..55740fa0 100644 --- a/MVMCoreUI/Models/Primitive Models/Color.swift +++ b/MVMCoreUI/Models/Primitive Models/Color.swift @@ -8,7 +8,19 @@ import UIKit - +/* + Use case: + For the Codable model define a variable such as + + var color: UIColor + + In the decode initializer: + color = try typeContainer.decode(Color.self, forKey: .color).uiColor + + In the encode initializer: + try container.encodeIfPresent(Color(uiColor: color), forKey: .color) + + */ public final class Color: Codable { //-------------------------------------------------- // MARK: - Properties From 2d0377acfc102dcb78367d1b8dd18f92ebb725d5 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 8 Jan 2020 09:30:55 -0500 Subject: [PATCH 11/16] small format. --- MVMCoreUI/Models/Primitive Models/Color.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Models/Primitive Models/Color.swift b/MVMCoreUI/Models/Primitive Models/Color.swift index 55740fa0..31206a5e 100644 --- a/MVMCoreUI/Models/Primitive Models/Color.swift +++ b/MVMCoreUI/Models/Primitive Models/Color.swift @@ -10,8 +10,7 @@ import UIKit /* Use case: - For the Codable model define a variable such as - + For the Codable model define a variable such as: var color: UIColor In the decode initializer: From 84462a197eca263e11f3ddb4cba59e2c3d384051 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 8 Jan 2020 09:37:47 -0500 Subject: [PATCH 12/16] changed comment. --- MVMCoreUI/Models/Primitive Models/Color.swift | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Models/Primitive Models/Color.swift b/MVMCoreUI/Models/Primitive Models/Color.swift index 31206a5e..e4c0e4fa 100644 --- a/MVMCoreUI/Models/Primitive Models/Color.swift +++ b/MVMCoreUI/Models/Primitive Models/Color.swift @@ -9,16 +9,9 @@ import UIKit /* - Use case: - For the Codable model define a variable such as: - var color: UIColor - - In the decode initializer: - color = try typeContainer.decode(Color.self, forKey: .color).uiColor - - In the encode initializer: - try container.encodeIfPresent(Color(uiColor: color), forKey: .color) - + UIColor is not supported by Codable. This Color class + effectively turns UIColor into a primitive class like + Int and String and can be used the same. */ public final class Color: Codable { //-------------------------------------------------- From 2365a2fab4022e8895f4c19d43db1ebd91849f81 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 9 Jan 2020 13:45:17 -0500 Subject: [PATCH 13/16] fixes --- MVMCoreUI/Molecules/ModuleMolecule.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index f5d580de..107dc3f9 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -20,8 +20,7 @@ open class ModuleMolecule: Container { } public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String: AnyHashable]?) { - #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.") - //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView. + super.setWithModel(model, delegateObject, additionalData) guard let moduleMoleculeModel = model as? ModuleMoleculeModel, let moduleModel = delegateObject?.moduleProtocol?.getModuleWithName(moduleMoleculeModel.moduleName) as? MoleculeProtocol else { From c8f8f8136db192845610902396e834d138f12113 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 9 Jan 2020 15:11:03 -0500 Subject: [PATCH 14/16] model changes --- MVMCoreUI/Models/Molecules/DropDownModel.swift | 5 +++++ MVMCoreUI/Models/Molecules/FooterModel.swift | 2 -- MVMCoreUI/Models/Molecules/HeaderModel.swift | 4 ++-- MVMCoreUI/Models/Molecules/ModuleMoleculeModel.swift | 4 ++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Models/Molecules/DropDownModel.swift b/MVMCoreUI/Models/Molecules/DropDownModel.swift index c0320737..95caa2b6 100644 --- a/MVMCoreUI/Models/Molecules/DropDownModel.swift +++ b/MVMCoreUI/Models/Molecules/DropDownModel.swift @@ -14,4 +14,9 @@ import Foundation public var backgroundColor: Color? public var label: String public var options: [String] + + public init(label: String, options: [String]) { + self.label = label + self.options = options + } } diff --git a/MVMCoreUI/Models/Molecules/FooterModel.swift b/MVMCoreUI/Models/Molecules/FooterModel.swift index 93f0a4e3..025538e6 100644 --- a/MVMCoreUI/Models/Molecules/FooterModel.swift +++ b/MVMCoreUI/Models/Molecules/FooterModel.swift @@ -11,7 +11,6 @@ import Foundation @objcMembers public class FooterModel: ContainerMoleculeProtocol { public static var identifier: String = "footer" - public var moleculeName: String? public var backgroundColor: Color? public var molecule: MoleculeProtocol @@ -27,7 +26,6 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) self.molecule = try typeContainer.decodeMolecule(codingKey: .molecule) } diff --git a/MVMCoreUI/Models/Molecules/HeaderModel.swift b/MVMCoreUI/Models/Molecules/HeaderModel.swift index 2f824773..1e4ab9f2 100644 --- a/MVMCoreUI/Models/Molecules/HeaderModel.swift +++ b/MVMCoreUI/Models/Molecules/HeaderModel.swift @@ -10,19 +10,18 @@ import Foundation @objcMembers public class HeaderModel: MoleculeContainerModel, MoleculeProtocol { public static var identifier: String = "header" - public var moleculeName: String? public var backgroundColor: Color? public var line: LineModel? enum HeaderCodingKeys: String, CodingKey { case moleculeName case line + case backgroundColor } required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: HeaderCodingKeys.self) - moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) // Default Values @@ -39,5 +38,6 @@ import Foundation var container = encoder.container(keyedBy: HeaderCodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(line, forKey: .line) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } diff --git a/MVMCoreUI/Models/Molecules/ModuleMoleculeModel.swift b/MVMCoreUI/Models/Molecules/ModuleMoleculeModel.swift index 35702824..56259942 100644 --- a/MVMCoreUI/Models/Molecules/ModuleMoleculeModel.swift +++ b/MVMCoreUI/Models/Molecules/ModuleMoleculeModel.swift @@ -17,6 +17,10 @@ open class ModuleMoleculeModel: MoleculeProtocol { case moduleName } + public init(_ moduleName: String) { + self.moduleName = moduleName + } + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) moduleName = try typeContainer.decode(String.self, forKey:.moduleName) From 8d2348fe633f8557096f6c20ad5e809ad9797ff6 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 9 Jan 2020 15:59:56 -0500 Subject: [PATCH 15/16] swiftify MoleculeDelegateProtocol --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ----- MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 2 +- .../MFViewController+Model.swift | 11 +++++- MVMCoreUI/BaseControllers/MFViewController.h | 3 +- MVMCoreUI/BaseControllers/MFViewController.m | 9 ----- MVMCoreUI/MVMCoreUI.h | 1 - .../AccordionMoleculeTableViewCell.swift | 4 +-- .../Items/DropDownFilterTableViewCell.swift | 4 +-- .../Molecules/Items/TabsTableViewCell.swift | 4 +-- MVMCoreUI/Molecules/ModuleMolecule.swift | 8 ++--- .../MVMCoreUIDelegateObject.swift | 6 ++-- .../ModelMoleculeDelegateProtocol.swift | 34 ++++++++++++++++++- .../Templates/MoleculeListTemplate.swift | 4 +-- 13 files changed, 59 insertions(+), 39 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 25fd66ea..15675325 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -52,7 +52,6 @@ 017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */; }; 017BEB7B236763000024EF95 /* LineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7A236763000024EF95 /* LineModel.swift */; }; 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */; }; - 0189255C239AA7EB004E8AFF /* ModuleDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0189255B239AA7EB004E8AFF /* ModuleDelegateProtocol.swift */; }; 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; @@ -123,7 +122,6 @@ D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; }; D28A837723C79FC600DFE4FC /* MFCustomButton+ActionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837623C79FC600DFE4FC /* MFCustomButton+ActionModel.swift */; }; D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -312,7 +310,6 @@ 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeViewProtocol.swift; sourceTree = ""; }; 017BEB7A236763000024EF95 /* LineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineModel.swift; sourceTree = ""; }; 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeObjectMapping.swift; sourceTree = ""; }; - 0189255B239AA7EB004E8AFF /* ModuleDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleDelegateProtocol.swift; sourceTree = ""; }; 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; @@ -382,7 +379,6 @@ D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = ""; }; D28A837623C79FC600DFE4FC /* MFCustomButton+ActionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFCustomButton+ActionModel.swift"; sourceTree = ""; }; D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeListCellProtocol.h; sourceTree = ""; }; - D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeDelegateProtocol.h; sourceTree = ""; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = ""; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = ""; }; D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = ""; }; @@ -1095,13 +1091,11 @@ D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */, D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */, D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */, - D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */, 012A88C7238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift */, D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */, D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */, 017BEB432362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift */, 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */, - 0189255B239AA7EB004E8AFF /* ModuleDelegateProtocol.swift */, ); path = OtherHandlers; sourceTree = ""; @@ -1231,7 +1225,6 @@ D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */, D29DF24E21E6A177003B2FB9 /* MFDigitTextField.h in Headers */, D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */, - D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */, D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */, D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */, D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */, @@ -1380,7 +1373,6 @@ D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */, 014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */, 012A88C4238D86E600FE3DA1 /* CollectionCellMoleculeProtocol.swift in Sources */, - 0189255C239AA7EB004E8AFF /* ModuleDelegateProtocol.swift in Sources */, 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, 017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 95b00cd7..17515e71 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -289,7 +289,7 @@ import UIKit self?.addConstraints(width: width, height: height, size: image?.size) self?.loadingSpinnerHeightConstraint?.constant = 0 if layoutWillChange { - self?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated?(self!) + self?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self!) } completionHandler(image,data,isFallbackImage) })} diff --git a/MVMCoreUI/BaseControllers/MFViewController+Model.swift b/MVMCoreUI/BaseControllers/MFViewController+Model.swift index afc022f8..264592c0 100644 --- a/MVMCoreUI/BaseControllers/MFViewController+Model.swift +++ b/MVMCoreUI/BaseControllers/MFViewController+Model.swift @@ -8,7 +8,14 @@ import Foundation -extension MFViewController: ModuleDelegateProtocol { +extension MFViewController: MoleculeDelegateProtocol { + public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? { + guard let name = name else { + return nil + } + return loadObject?.modulesJSON?.optionalDictionaryForKey(name) + } + public func getModuleWithName(_ moduleName: String) -> Model? { guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moduleName), let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), @@ -29,3 +36,5 @@ public extension MFViewController { (self as? TemplateProtocol)?.parseTemplateJSON() } } + +//MoleculeDelegateProtocol diff --git a/MVMCoreUI/BaseControllers/MFViewController.h b/MVMCoreUI/BaseControllers/MFViewController.h index c1415df4..cd96a07f 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.h +++ b/MVMCoreUI/BaseControllers/MFViewController.h @@ -27,14 +27,13 @@ #import #import #import -#import @class MainMenuViewController; @class MVMCoreUITabBarPageControlViewController; @class MVMAnimationManager; @class DelegateObject; -@interface MFViewController : UIViewController +@interface MFViewController : UIViewController // Stores the load object that this screen was loaded with. @property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject; diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index 153af17f..1d97efd9 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -834,15 +834,6 @@ } } -#pragma mark - MoleculeDelegateProtocol - -- (NSDictionary *)getModuleWithName:(NSString *)name { - if (!name) { - return nil; - } - return [self.loadObject.modulesJSON dict:name]; -} - #pragma mark - adobe analytics - (nullable NSArray *)additionalActionsToTrackWithMainActionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 795298b3..ff9b4087 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -20,7 +20,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import -#import #import #import diff --git a/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift index 075d33f1..d6a5e05d 100644 --- a/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift @@ -34,9 +34,9 @@ import UIKit } if accordionButton.isSelected { - delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: .automatic) + delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .automatic) } else { - delegateObject?.moleculeDelegate?.removeMolecules?(molecules, sender: self, animation: .automatic) + delegateObject?.moleculeDelegate?.removeMolecules(molecules, sender: self, animation: .automatic) } if (json?.boolForKey("hideSeparatorWhenExpanded") ?? false) && (self.bottomSeparatorView?.shouldBeVisible() ?? false) { diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index a9d9c360..a2ca4383 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -39,10 +39,10 @@ import UIKit if self.previousIndex != NSNotFound { let previousMolecules = moleculesArrays[self.previousIndex] - self.delegateObject?.moleculeDelegate?.removeMolecules?(previousMolecules, sender: self, animation: .fade) + self.delegateObject?.moleculeDelegate?.removeMolecules(previousMolecules, sender: self, animation: .fade) } let molecules = moleculesArrays[index] - self.delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: .fade) + self.delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .fade) self.previousIndex = index } } diff --git a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift index b75f4600..d9626ae0 100644 --- a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift @@ -58,7 +58,7 @@ extension TabsTableViewCell: TopTabbarDelegate { public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool { if let moleculesArrays = json?.arrayForKey(KeyMolecules), let molecules = moleculesArrays[topTabbar.selectedIndex] as? [[AnyHashable: Any]] { - delegateObject?.moleculeDelegate?.removeMolecules?(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left) + delegateObject?.moleculeDelegate?.removeMolecules(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left) } previousTabIndex = tabs.selectedIndex return true @@ -67,7 +67,7 @@ extension TabsTableViewCell: TopTabbarDelegate { public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) { if let moleculesArrays = json?.arrayForKey(KeyMolecules), let molecules = moleculesArrays[index] as? [[AnyHashable: Any]] { - delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: index < previousTabIndex ? .left : .right) + delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: index < previousTabIndex ? .left : .right) } } } diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index 107dc3f9..863df271 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -23,7 +23,7 @@ open class ModuleMolecule: Container { super.setWithModel(model, delegateObject, additionalData) guard let moduleMoleculeModel = model as? ModuleMoleculeModel, - let moduleModel = delegateObject?.moduleProtocol?.getModuleWithName(moduleMoleculeModel.moduleName) as? MoleculeProtocol else { + let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMoleculeModel.moduleName) as? MoleculeProtocol else { // Critical error return } @@ -49,7 +49,7 @@ open class ModuleMolecule: Container { public static func estimatedHeight(forRow molecule: MoleculeProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let moduleMolecule = molecule as? ModuleMoleculeModel, - let moduleModel = delegateObject?.moduleProtocol?.getModuleWithName(moduleMolecule.moduleName) as? MoleculeProtocol, + let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName) as? MoleculeProtocol, let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moduleModel) as? ModelMoleculeViewProtocol.Type, let height = classType.estimatedHeight(forRow: moduleModel, delegateObject: delegateObject)else { // Critical error @@ -60,7 +60,7 @@ open class ModuleMolecule: Container { public override func nameForReuse(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let moduleMolecule = model as? ModuleMoleculeModel, - let moduleModel = delegateObject?.moduleProtocol?.getModuleWithName(moduleMolecule.moduleName) as? MoleculeProtocol, + let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName) as? MoleculeProtocol, let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moduleModel) as? ModelMoleculeViewProtocol, let name = classType.nameForReuse(moduleModel, delegateObject) else { // Critical error @@ -73,7 +73,7 @@ open class ModuleMolecule: Container { public static func requiredModules(_ molecule: MoleculeProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { guard let moduleName = (molecule as? ModuleMoleculeModel)?.moduleName, - let _ = delegateObject?.moduleProtocol?.getModuleWithName(moduleName) else { + let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else { if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { error?.pointee = errorObject MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift index 6a7fbc05..f64162db 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift @@ -12,16 +12,14 @@ open class MVMCoreUIDelegateObject: DelegateObject { public weak var formValidationProtocol: FormValidationProtocol? public weak var buttonDelegate: ButtonDelegateProtocol? public weak var uiTextFieldDelegate: UITextFieldDelegate? - public weak var moleculeDelegate: MoleculeDelegateProtocol? - public var moduleProtocol: ModuleDelegateProtocol? - + public var moleculeDelegate: MoleculeDelegateProtocol? + open override func setAll(withDelegate delegate: Any) { super.setAll(withDelegate: delegate) formValidationProtocol = delegate as? FormValidationProtocol buttonDelegate = delegate as? ButtonDelegateProtocol uiTextFieldDelegate = delegate as? UITextFieldDelegate moleculeDelegate = delegate as? MoleculeDelegateProtocol - moduleProtocol = delegate as? ModuleDelegateProtocol } class func delegateObject(from controller: MVMCoreViewControllerProtocol?) -> MVMCoreUIDelegateObject? { diff --git a/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift b/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift index dd79ee3d..1ea4df38 100644 --- a/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift +++ b/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift @@ -8,7 +8,39 @@ import Foundation -public protocol ModelMoleculeDelegateProtocol { +public protocol MoleculeDelegateProtocol { + + /// returns a module for the corresponding module name. + func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? + func getModuleWithName(_ moleculeName: String) -> Model? + + /// Notifies the delegate that the molecule layout update. Should be called when the layout may change due to an async method. + func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) //optional + + /// Asks the delegate to add or remove molecules. + //optional + func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) + func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) + + //optional func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) } + +extension MoleculeDelegateProtocol { + public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { + // Do Nothing + } + public func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { + // Do nothpublic ing + } + public func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { + // Do nothing + } + public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + // Do nothpublic ing + } + public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + // Do nothing + } +} diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 94c0d009..ecd55350 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -8,7 +8,7 @@ import UIKit -open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol, ModelMoleculeDelegateProtocol { +open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol { public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? var observer: NSKeyValueObservation? @@ -129,7 +129,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } // MARK: - MoleculeDelegateProtocol - open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { + open func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { if let tableView = tableView { let point = molecule.convert(molecule.bounds.origin, to: tableView) if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false { From a7072fe1a0260c033ad2eff9197faf13d2bceba3 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 9 Jan 2020 16:01:27 -0500 Subject: [PATCH 16/16] remove template --- MVMCoreUI.xcodeproj/project.pbxproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 15675325..ace76ad4 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -558,13 +558,6 @@ path = ModelProtocols; sourceTree = ""; }; - 012A889A238898C600FE3DA1 /* Template */ = { - isa = PBXGroup; - children = ( - ); - path = Template; - sourceTree = ""; - }; 012A88EF23985E0100FE3DA1 /* Primitive Models */ = { isa = PBXGroup; children = ( @@ -601,7 +594,6 @@ 014AA72023C501E2006F3E93 /* Container */, 011B58EE23A2AA850085F53C /* ModelProtocols */, 012A88EF23985E0100FE3DA1 /* Primitive Models */, - 012A889A238898C600FE3DA1 /* Template */, 946EE1B5237B663A0036751F /* Extensions */, 01EB368723609801006832FA /* Molecules */, );