From b443c4a3897c0031019af5dfd5d9a76d5b2f1f0a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 2 Dec 2019 17:33:06 -0500 Subject: [PATCH 01/25] Reducing constraints. --- .../Atoms/Views/CheckboxWithLabelView.swift | 49 +++++-------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index f148863b..55f32ae9 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -7,7 +7,7 @@ // -@objcMembers open class CheckboxWithLabelView: ViewConstrainingView { +@objcMembers open class CheckboxWithLabelView: View { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- @@ -33,12 +33,10 @@ // MARK: - Constraints //-------------------------------------------------- - var checkboxWidthConstraint: NSLayoutConstraint? var checkboxHeightConstraint: NSLayoutConstraint? var checkboxTopConstraint: NSLayoutConstraint? var checkboxBottomConstraint: NSLayoutConstraint? var checkboxCenterYConstraint: NSLayoutConstraint? - var centerLabelCheckboxConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Life Cycle @@ -56,33 +54,24 @@ label.text = "" - let dimension = sizeObject?.getValueBasedOnApplicationWidth() ?? Checkbox.defaultHeightWidth - checkboxWidthConstraint = checkbox.heightAnchor.constraint(equalToConstant: dimension) - checkboxWidthConstraint?.isActive = true - checkboxHeightConstraint = checkbox.widthAnchor.constraint(equalToConstant: dimension) - checkboxHeightConstraint?.isActive = true - checkbox.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true - checkbox.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor).isActive = true - layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: checkbox.bottomAnchor).isActive = true - let checboxBottom = checkbox.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) - checboxBottom.priority = UILayoutPriority(249) - checboxBottom.isActive = true - - // Allows various positions of checkbox. checkboxBottomConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: checkbox.bottomAnchor) + checkboxBottomConstraint?.priority = .defaultHigh + checkboxBottomConstraint?.isActive = true + checkboxTopConstraint = checkbox.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor) + checkboxTopConstraint?.priority = .defaultHigh + checkboxTopConstraint?.isActive = true + checkboxCenterYConstraint = checkbox.centerYAnchor.constraint(equalTo: centerYAnchor) - centerLabelCheckboxConstraint = label.centerYAnchor.constraint(equalTo: checkbox.centerYAnchor) label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true layoutMarginsGuide.trailingAnchor.constraint(equalTo: label.trailingAnchor).isActive = true label.leadingAnchor.constraint(equalTo: checkbox.trailingAnchor, constant: PaddingTwo).isActive = true - layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true let bottomLabelConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: label.bottomAnchor) - bottomLabelConstraint.priority = UILayoutPriority(249) + bottomLabelConstraint.priority = UILayoutPriority(250) bottomLabelConstraint.isActive = true alignCheckbox(.center) @@ -102,7 +91,7 @@ setupView() } - public convenience init() { + public convenience override init() { self.init(frame: .zero) } @@ -125,19 +114,16 @@ checkboxBottomConstraint?.isActive = false checkboxTopConstraint?.isActive = false checkboxCenterYConstraint?.isActive = true - centerLabelCheckboxConstraint?.isActive = true case .top: checkboxBottomConstraint?.isActive = false checkboxTopConstraint?.isActive = true checkboxCenterYConstraint?.isActive = false - centerLabelCheckboxConstraint?.isActive = false case .bottom: checkboxBottomConstraint?.isActive = true checkboxTopConstraint?.isActive = false checkboxCenterYConstraint?.isActive = false - centerLabelCheckboxConstraint?.isActive = false } } } @@ -145,7 +131,7 @@ /// MARK: - Molecular extension CheckboxWithLabelView { - override open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return CGFloat(Checkbox.defaultHeightWidth) } @@ -153,29 +139,18 @@ extension CheckboxWithLabelView { super.updateView(size) label.updateView(size) - - if self.checkbox.responds(to: #selector(self.updateView(_:))) { - if let dimension = sizeObject?.getValueBased(onSize: size) { - checkboxWidthConstraint?.constant = dimension - checkboxHeightConstraint?.constant = dimension - checkbox.updateView(size) - } - } - layoutIfNeeded() } - override open func alignment() -> UIStackView.Alignment { + open func alignment() -> UIStackView.Alignment { return .leading } - open override func resetConstraints() { - super.resetConstraints() + open func resetConstraints() { checkboxCenterYConstraint?.isActive = false checkboxBottomConstraint?.isActive = false checkboxTopConstraint?.isActive = false - centerLabelCheckboxConstraint?.isActive = false } open override func reset() { From 9b53f4bac04e3ba6e9868ad46d02ca213c629ebe Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 3 Dec 2019 09:07:43 -0500 Subject: [PATCH 02/25] Paired down constraints. Made variables public. Mild formatting. --- .../Atoms/Views/CheckboxWithLabelView.swift | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 55f32ae9..30722295 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -19,9 +19,9 @@ // MARK: - Properties //-------------------------------------------------- - var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0) + public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0) - var checkboxPosition: CheckboxPosition = .center + public var checkboxPosition: CheckboxPosition = .center public enum CheckboxPosition: String { case center @@ -33,10 +33,10 @@ // MARK: - Constraints //-------------------------------------------------- - var checkboxHeightConstraint: NSLayoutConstraint? - var checkboxTopConstraint: NSLayoutConstraint? - var checkboxBottomConstraint: NSLayoutConstraint? - var checkboxCenterYConstraint: NSLayoutConstraint? + public var checkboxHeightConstraint: NSLayoutConstraint? + public var checkboxTopConstraint: NSLayoutConstraint? + public var checkboxBottomConstraint: NSLayoutConstraint? + public var checkboxCenterYConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Life Cycle @@ -81,12 +81,7 @@ // MARK: - Initializers //-------------------------------------------------- - required public init?(coder: NSCoder) { - super.init(coder: coder) - fatalError("xib file is not implemented for CheckboxWithLabelView") - } - - override public init(frame: CGRect) { + public override init(frame: CGRect) { super.init(frame: frame) setupView() } @@ -101,6 +96,11 @@ alignCheckbox(position) } + required public init?(coder: NSCoder) { + super.init(coder: coder) + fatalError("xib file is not implemented for CheckboxWithLabelView") + } + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- @@ -128,11 +128,11 @@ } } -/// MARK: - Molecular +// MARK: - Molecular extension CheckboxWithLabelView { - open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return CGFloat(Checkbox.defaultHeightWidth) + open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 200 } @objc override open func updateView(_ size: CGFloat) { @@ -142,10 +142,6 @@ extension CheckboxWithLabelView { layoutIfNeeded() } - open func alignment() -> UIStackView.Alignment { - return .leading - } - open func resetConstraints() { checkboxCenterYConstraint?.isActive = false From aaa8e4132ebb454db8a3cd8244a7ea8d64128bf0 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 4 Dec 2019 16:25:31 -0500 Subject: [PATCH 03/25] Brought back resizing to checkbox. --- MVMCoreUI/Atoms/Views/Checkbox.swift | 11 +++++++++-- MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 370f5826..2dc32675 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -16,6 +16,8 @@ import MVMCore // MARK: - Properties //-------------------------------------------------- + public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0) + // Form Validation var isRequired = false var fieldKey: String? @@ -117,8 +119,8 @@ import MVMCore // MARK: - Constraints //-------------------------------------------------- - private var heightConstraint: NSLayoutConstraint? - private var widthConstraint: NSLayoutConstraint? + public var heightConstraint: NSLayoutConstraint? + public var widthConstraint: NSLayoutConstraint? /// Updates the height and width anchors of the Checkbox with the assigned value. public var heigthWidthConstant: CGFloat = Checkbox.defaultHeightWidth { @@ -398,6 +400,11 @@ import MVMCore public func updateView(_ size: CGFloat) { + if let dimension = sizeObject?.getValueBased(onSize: size) { + widthConstraint?.constant = dimension + heightConstraint?.constant = dimension + } + layoutIfNeeded() } diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 30722295..b2ef5ab2 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -19,8 +19,6 @@ // MARK: - Properties //-------------------------------------------------- - public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0) - public var checkboxPosition: CheckboxPosition = .center public enum CheckboxPosition: String { @@ -139,6 +137,7 @@ extension CheckboxWithLabelView { super.updateView(size) label.updateView(size) + checkbox.updateView(size) layoutIfNeeded() } From a7989c589f6f6bfae225d71ae8ea5253525a1c10 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 9 Dec 2019 11:03:31 -0500 Subject: [PATCH 04/25] Increased the tappable space of the Checkbox. --- MVMCoreUI/Atoms/Views/Checkbox.swift | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 2dc32675..6d831d82 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -351,18 +351,14 @@ import MVMCore open override func touchesEnded(_ touches: Set, with event: UIEvent?) { - sendActions(for: touchIsAcceptablyOutside(touches.first) ? .touchUpOutside : .touchUpInside) + sendActions(for: .touchUpInside) } - func touchIsAcceptablyOutside(_ touch: UITouch?) -> Bool { - let endLocation = touch?.location(in: self) - let x = endLocation?.x ?? 0.0 - let y = endLocation?.y ?? 0.0 - let faultTolerance: CGFloat = 20.0 - let widthLimit = CGFloat(bounds.size.width + faultTolerance) - let heightLimt = CGFloat(bounds.size.height + faultTolerance) + override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - return x < -faultTolerance || y < -faultTolerance || x > widthLimit || y > heightLimt + let faultTolerance: CGFloat = 20.0 + let area = bounds.insetBy(dx: -faultTolerance, dy: -faultTolerance) + return area.contains(point) } override open func accessibilityActivate() -> Bool { @@ -413,7 +409,7 @@ import MVMCore FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) guard let dictionary = json else { return } - + groupName = dictionary.optionalStringForKey("groupName") fieldValue = dictionary.optionalStringForKey("value") if let fieldKey = dictionary[KeyFieldKey] as? String { @@ -470,7 +466,7 @@ import MVMCore // MARK:- FormValidationProtocol extension Checkbox: FormValidationFormFieldProtocol { - + public func formFieldGroupName() -> String? { return groupName } From 335649860b8dfeccaa9fc95bb830aa4dae481544 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 10 Dec 2019 11:15:09 -0500 Subject: [PATCH 05/25] constraint adjustments. --- MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index b2ef5ab2..0cbfee07 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -55,11 +55,9 @@ checkbox.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true checkboxBottomConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: checkbox.bottomAnchor) - checkboxBottomConstraint?.priority = .defaultHigh checkboxBottomConstraint?.isActive = true checkboxTopConstraint = checkbox.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor) - checkboxTopConstraint?.priority = .defaultHigh checkboxTopConstraint?.isActive = true checkboxCenterYConstraint = checkbox.centerYAnchor.constraint(equalTo: centerYAnchor) @@ -68,10 +66,13 @@ layoutMarginsGuide.trailingAnchor.constraint(equalTo: label.trailingAnchor).isActive = true label.leadingAnchor.constraint(equalTo: checkbox.trailingAnchor, constant: PaddingTwo).isActive = true + layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true + let bottomLabelConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: label.bottomAnchor) - bottomLabelConstraint.priority = UILayoutPriority(250) bottomLabelConstraint.isActive = true + label.heightAnchor.constraint(greaterThanOrEqualToConstant: 15).isActive = true + alignCheckbox(.center) } From ed1897062574eb5e6fad797a75e10b796ef2a4bd Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 12 Dec 2019 09:23:04 -0500 Subject: [PATCH 06/25] correcting errors. Improving Control. --- MVMCoreUI/Atoms/Views/Checkbox.swift | 16 ++++++++++------ MVMCoreUI/BaseClasses/Control.swift | 21 ++++++++++++++++++--- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 6d831d82..27576bc8 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -11,7 +11,7 @@ import MVMCore /** This class expects its height and width to be equal. */ -@objcMembers open class Checkbox: UIControl, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol { +@objcMembers open class Checkbox: Control, MVMCoreUIViewConstrainingProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -149,7 +149,7 @@ import MVMCore fatalError("xib file is not implemented for Checkbox.") } - public convenience init() { + public convenience override init() { self.init(frame:.zero) } @@ -182,7 +182,8 @@ import MVMCore layer.borderColor = borderColor.cgColor } - open func setupView() { + open override func setupView() { + super.setupView() guard constraints.isEmpty else { return } @@ -374,7 +375,8 @@ import MVMCore return true } - open func reset() { + open override func reset() { + super.reset() isEnabled(true) shapeLayer?.removeAllAnimations() @@ -394,7 +396,8 @@ import MVMCore setupView() } - public func updateView(_ size: CGFloat) { + public override func updateView(_ size: CGFloat) { + super.updateView(size) if let dimension = sizeObject?.getValueBased(onSize: size) { widthConstraint?.constant = dimension @@ -404,7 +407,8 @@ import MVMCore layoutIfNeeded() } - public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) self.delegateObject = delegateObject FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index fdf8204f..79db2c6d 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -8,17 +8,25 @@ import UIKit -public class Control: UIControl { - var json: [AnyHashable: Any]? +@objcMembers open class Control: UIControl { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public var json: [AnyHashable: Any]? private var initialSetupPerformed = false + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override init(frame: CGRect) { super.init(frame: .zero) initialSetup() } - init() { + public init() { super.init(frame: .zero) initialSetup() } @@ -28,6 +36,10 @@ public class Control: UIControl { initialSetup() } + //-------------------------------------------------- + // MARK: - Setup + //-------------------------------------------------- + public func initialSetup() { if !initialSetupPerformed { initialSetupPerformed = true @@ -36,7 +48,9 @@ public class Control: UIControl { } } +// MARK: - MVMCoreViewProtocol extension Control: MVMCoreViewProtocol { + public func updateView(_ size: CGFloat) { } @@ -47,6 +61,7 @@ extension Control: MVMCoreViewProtocol { } } +// MARK: - MVMCoreUIMoleculeViewProtocol extension Control: MVMCoreUIMoleculeViewProtocol { public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { self.json = json From 3db8cf2c3b7ca6d4d98cea04a49f82d8f4657c9e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 12 Dec 2019 09:27:13 -0500 Subject: [PATCH 07/25] Reversed the array to first check views at the front. --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index 13faeb42..2c14f9be 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -237,11 +237,13 @@ import UIKit var queue = [UIView]() - for view in views { + // Reversed the array to first check views at the front. + for view in views.reversed() { // Only one Label will have a hero in a table cell. if let label = view as? Label, label.hero != nil { return label } + queue.append(contentsOf: view.subviews) } From e5acf63e6faa5d5e215fb8d698af9ed61d94c3f4 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 12 Dec 2019 10:03:41 -0500 Subject: [PATCH 08/25] container testing --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Containers/Container.swift | 197 ++++++++++++++++++ .../MVMCoreUIViewConstrainingProtocol.h | 8 +- 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Containers/Container.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 900edec2..70aab44f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -47,6 +47,7 @@ D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */; }; D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */; }; + D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D260D7B122D65BDD007E7233 /* MVMCoreUIPageControl.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7AF22D65BDD007E7233 /* MVMCoreUIPageControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */; }; D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -245,6 +246,7 @@ D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISwitch.m; sourceTree = ""; }; D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIStackableViewController.h; sourceTree = ""; }; D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = ""; }; + D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D260D7AF22D65BDD007E7233 /* MVMCoreUIPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPageControl.h; sourceTree = ""; }; D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = ""; }; D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = ""; }; @@ -669,6 +671,7 @@ D29DF2B721E7BE79003B2FB9 /* TabBarController */, D29DF2B621E7BE66003B2FB9 /* SplitViewController */, D2B18B93236214AD00A9AEDC /* NavigationController.swift */, + D243859823A16B1800332775 /* Container.swift */, ); path = Containers; sourceTree = ""; @@ -1146,6 +1149,7 @@ D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */, D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */, + D243859923A16B1800332775 /* Container.swift in Sources */, D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */, D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */, D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift new file mode 100644 index 00000000..ca91964d --- /dev/null +++ b/MVMCoreUI/Containers/Container.swift @@ -0,0 +1,197 @@ +// +// Container.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 12/11/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +protocol ContainerModelProtocol { + var horizontalAlignment: UIStackView.Alignment { get set } + var verticalAlignment: UIStackView.Alignment { get set } +} + +class ContainerHelper: NSObject { + var leftConstraint: NSLayoutConstraint? + var topConstraint: NSLayoutConstraint? + var bottomConstraint: NSLayoutConstraint? + var rightConstraint: NSLayoutConstraint? + + var alignCenterHorizontalConstraint: NSLayoutConstraint? + var alignCenterLeftConstraint: NSLayoutConstraint? + var alignCenterRightConstraint: NSLayoutConstraint? + + var alignCenterVerticalConstraint: NSLayoutConstraint? + var alignCenterTopConstraint: NSLayoutConstraint? + var alignCenterBottomConstraint: NSLayoutConstraint? + + var leftLowConstraint: NSLayoutConstraint? + var topLowConstraint: NSLayoutConstraint? + var bottomLowConstraint: NSLayoutConstraint? + var rightLowConstraint: NSLayoutConstraint? + + func constrainView(_ view: UIView) { + guard let margins = view.superview?.layoutMarginsGuide else { return } + leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor) + leftConstraint?.isActive = true + + topConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor) + topConstraint?.isActive = true + + rightConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor) + rightConstraint?.isActive = true + + bottomConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor) + bottomConstraint?.isActive = true + + alignCenterHorizontalConstraint = view.centerXAnchor.constraint(equalTo: margins.centerXAnchor) + alignCenterLeftConstraint = view.leftAnchor.constraint(greaterThanOrEqualTo: margins.leftAnchor) + alignCenterRightConstraint = margins.rightAnchor.constraint(greaterThanOrEqualTo: view.rightAnchor) + + alignCenterVerticalConstraint = view.centerYAnchor.constraint(equalTo: margins.centerYAnchor) + alignCenterTopConstraint = view.topAnchor.constraint(greaterThanOrEqualTo: margins.topAnchor) + alignCenterBottomConstraint = margins.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor) + + leftLowConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor) + leftLowConstraint?.priority = UILayoutPriority(rawValue: 200) + leftLowConstraint?.isActive = true + + topLowConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor) + topLowConstraint?.priority = UILayoutPriority(rawValue: 200) + topLowConstraint?.isActive = true + + rightLowConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor) + rightLowConstraint?.priority = UILayoutPriority(rawValue: 200) + rightLowConstraint?.isActive = true + + bottomLowConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor) + bottomLowConstraint?.priority = UILayoutPriority(rawValue: 200) + bottomLowConstraint?.isActive = true + + setAccessibility(view) + } + + func setAccessibility(_ view: UIView) { + guard let superView = view.superview else { return } + superView.isAccessibilityElement = false + if let elements = view.accessibilityElements { + superView.accessibilityElements = elements + } else { + superView.accessibilityElements = [view] + } + } + + func alignHorizontal(_ alignment: UIStackView.Alignment) { + switch alignment { + case .center: + alignCenterHorizontalConstraint?.isActive = true + alignCenterLeftConstraint?.isActive = true + alignCenterRightConstraint?.isActive = true + leftConstraint?.isActive = false + rightConstraint?.isActive = false + case .leading: + alignCenterHorizontalConstraint?.isActive = false + alignCenterLeftConstraint?.isActive = false + alignCenterRightConstraint?.isActive = true + leftConstraint?.isActive = true + rightConstraint?.isActive = false + case .trailing: + alignCenterHorizontalConstraint?.isActive = false + alignCenterLeftConstraint?.isActive = true + alignCenterRightConstraint?.isActive = false + leftConstraint?.isActive = false + rightConstraint?.isActive = true + case .fill: + alignCenterHorizontalConstraint?.isActive = false + alignCenterLeftConstraint?.isActive = false + alignCenterRightConstraint?.isActive = false + leftConstraint?.isActive = true + rightConstraint?.isActive = true + default: break + } + } + + func alignVertical(_ alignment: UIStackView.Alignment) { + switch alignment { + case .center: + alignCenterVerticalConstraint?.isActive = true + alignCenterTopConstraint?.isActive = true + alignCenterBottomConstraint?.isActive = true + topConstraint?.isActive = false + bottomConstraint?.isActive = false + case .leading: + alignCenterVerticalConstraint?.isActive = false + alignCenterTopConstraint?.isActive = false + alignCenterBottomConstraint?.isActive = true + topConstraint?.isActive = true + bottomConstraint?.isActive = false + case .trailing: + alignCenterVerticalConstraint?.isActive = false + alignCenterTopConstraint?.isActive = true + alignCenterBottomConstraint?.isActive = false + topConstraint?.isActive = false + bottomConstraint?.isActive = true + case .fill: + alignCenterVerticalConstraint?.isActive = false + alignCenterTopConstraint?.isActive = false + alignCenterBottomConstraint?.isActive = false + topConstraint?.isActive = true + bottomConstraint?.isActive = true + default: break + } + } + + func set(with model: ContainerModelProtocol) { + alignHorizontal(model.horizontalAlignment) + alignVertical(model.verticalAlignment) + } + + static func getAlignment(for string: String) -> UIStackView.Alignment? { + switch string { + case "leading": + return .leading + case "trailing": + return .trailing + case "center": + return .center + case "fill": + return .fill + default: + return nil + } + } +} + +class Container: View { + var model: ContainerModelProtocol? + var view: UIView? + let containerHelper = ContainerHelper() +} + +// MARK: - MVMCoreViewProtocol +extension Container { + open override func updateView(_ size: CGFloat) { + super.updateView(size) + (view as? MVMCoreViewProtocol)?.updateView(size) + MFStyler.setMarginsFor(self, size: size, defaultHorizontal: true, top: 0, bottom: 0) + } + + /// Will be called only once. + open override func setupView() { + super.setupView() + backgroundColor = .clear + } +} + +// MARK: - MVMCoreUIMoleculeViewProtocol +extension Container { + override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) { + containerHelper.alignHorizontal(alignment) + } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment { + containerHelper.alignHorizontal(alignment) + } + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewConstrainingProtocol.h b/MVMCoreUI/OtherHandlers/MVMCoreUIViewConstrainingProtocol.h index afea0ef6..a2ac2340 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewConstrainingProtocol.h +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewConstrainingProtocol.h @@ -16,7 +16,13 @@ - (BOOL)needsToBeConstrained; /// The alignment if constrained. -- (UIStackViewAlignment)alignment; +- (UIStackViewAlignment)alignment __deprecated; + +/// The alignment if constrained. +- (UIStackViewAlignment)horizontalAlignment; + +/// The alignment if constrained. +- (UIStackViewAlignment)verticalAlignment; /// Can be used to override any standard constraints that may be added. - (BOOL)useStandardConstraints; From 8804e21d3ce08f3faf63d96431c195ff5a344729 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 12 Dec 2019 14:42:32 -0500 Subject: [PATCH 09/25] New constant. Updated control to work with Apple's design guidelines with control. Updates made to checkbox and checkboxLabel. --- MVMCoreUI/Atoms/Views/Checkbox.swift | 8 ------- .../Atoms/Views/CheckboxWithLabelView.swift | 3 +-- MVMCoreUI/BaseClasses/Control.swift | 21 +++++++++++++++---- MVMCoreUI/Utility/MVMCoreUIConstants.h | 4 ++++ MVMCoreUI/Utility/MVMCoreUIConstants.m | 4 ++++ 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 27576bc8..a206953a 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -140,7 +140,6 @@ import MVMCore accessibilityTraits = .button accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint") updateAccessibilityLabel() - setupView() } /// There is currently no intention on using xib files. @@ -355,13 +354,6 @@ import MVMCore sendActions(for: .touchUpInside) } - override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - - let faultTolerance: CGFloat = 20.0 - let area = bounds.insetBy(dx: -faultTolerance, dy: -faultTolerance) - return area.contains(point) - } - override open func accessibilityActivate() -> Bool { sendActions(for: .touchUpInside) return true diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 0cbfee07..404764fe 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -30,8 +30,7 @@ //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- - - public var checkboxHeightConstraint: NSLayoutConstraint? + public var checkboxTopConstraint: NSLayoutConstraint? public var checkboxBottomConstraint: NSLayoutConstraint? public var checkboxCenterYConstraint: NSLayoutConstraint? diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index 79db2c6d..5774ff5a 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -33,7 +33,7 @@ import UIKit public required init?(coder: NSCoder) { super.init(coder: coder) - initialSetup() + fatalError("Control does not support xib.") } //-------------------------------------------------- @@ -41,18 +41,31 @@ import UIKit //-------------------------------------------------- public func initialSetup() { + if !initialSetupPerformed { initialSetupPerformed = true setupView() } } + + //-------------------------------------------------- + // MARK: - UITouch + //-------------------------------------------------- + + 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) + } } // MARK: - MVMCoreViewProtocol extension Control: MVMCoreViewProtocol { - public func updateView(_ size: CGFloat) { - } + public func updateView(_ size: CGFloat) {} /// Will be called only once. public func setupView() { @@ -63,7 +76,7 @@ extension Control: MVMCoreViewProtocol { // MARK: - MVMCoreUIMoleculeViewProtocol extension Control: MVMCoreUIMoleculeViewProtocol { - public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { self.json = json if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.h b/MVMCoreUI/Utility/MVMCoreUIConstants.h index 778ede4f..e5587745 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.h +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.h @@ -77,3 +77,7 @@ typedef NS_ENUM(NSInteger, CoreUIErrorCode) { ErrorCodeModuleMolecule = 100, ErrorCodeListMolecule = 101 }; + +#pragma mark - Apple Design Guidelines + +extern CGFloat const MinimumTappableArea; diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.m b/MVMCoreUI/Utility/MVMCoreUIConstants.m index 26636266..6211cfee 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.m +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.m @@ -69,3 +69,7 @@ BOOL DisableAnimations = NO; // Hand Scroll Key NSString * const KeyHandScrollAnimation = @"handScrollAnimation"; NSString * const KeyHandScroll = @"hand_scroll"; + +#pragma mark - Apple Design Guidelines + +CGFloat const MinimumTappableArea = 44.0f; From be1b867a9a4a45acff0cee389518a873a065f326 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 12 Dec 2019 14:50:52 -0500 Subject: [PATCH 10/25] testing container ideas --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +++ MVMCoreUI/Containers/Container.swift | 33 +++++++++++++------ MVMCoreUI/Molecules/MoleculeContainer.swift | 34 ++++++++++++++++++++ MVMCoreUI/Molecules/StandardFooterView.swift | 15 ++------- MVMCoreUI/Molecules/StandardHeaderView.swift | 14 ++------ 5 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 MVMCoreUI/Molecules/MoleculeContainer.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 70aab44f..73ecaabf 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -198,6 +198,7 @@ D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; }; D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; }; D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; }; + D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; }; DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; @@ -402,6 +403,7 @@ D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = ""; }; D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = ""; }; D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = ""; }; DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = ""; }; DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; @@ -627,6 +629,7 @@ D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */, 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, + D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, ); path = Molecules; sourceTree = ""; @@ -1138,6 +1141,7 @@ D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */, D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */, D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */, + D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */, D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */, D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift index ca91964d..2af6e46a 100644 --- a/MVMCoreUI/Containers/Container.swift +++ b/MVMCoreUI/Containers/Container.swift @@ -8,12 +8,14 @@ import UIKit -protocol ContainerModelProtocol { +public protocol ContainerModelProtocol { var horizontalAlignment: UIStackView.Alignment { get set } var verticalAlignment: UIStackView.Alignment { get set } + var useHorizontalMargins: Bool { get set } + var useVerticalMargins: Bool { get set } } -class ContainerHelper: NSObject { +public class ContainerHelper: NSObject { var leftConstraint: NSLayoutConstraint? var topConstraint: NSLayoutConstraint? var bottomConstraint: NSLayoutConstraint? @@ -164,34 +166,45 @@ class ContainerHelper: NSObject { } } -class Container: View { +open class Container: View { var model: ContainerModelProtocol? var view: UIView? let containerHelper = ContainerHelper() + + var topMarginPadding: CGFloat = 0 + var bottomMarginPadding: CGFloat = 0 } // MARK: - MVMCoreViewProtocol -extension Container { - open override func updateView(_ size: CGFloat) { +public extension Container { + override func updateView(_ size: CGFloat) { super.updateView(size) (view as? MVMCoreViewProtocol)?.updateView(size) - MFStyler.setMarginsFor(self, size: size, defaultHorizontal: true, top: 0, bottom: 0) + MFStyler.setMarginsFor(self, size: size, defaultHorizontal: model?.useHorizontalMargins ?? true, top: model?.useHorizontalMargins ?? true ? topMarginPadding : 0, bottom: model?.useHorizontalMargins ?? true ? bottomMarginPadding : 0) } /// Will be called only once. - open override func setupView() { + override func setupView() { super.setupView() backgroundColor = .clear } } // MARK: - MVMCoreUIMoleculeViewProtocol -extension Container { +public extension Container { override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + + if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { containerHelper.alignHorizontal(alignment) - } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment { + } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { containerHelper.alignHorizontal(alignment) } + + if let verticalAlignmentString = json?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { + containerHelper.alignHorizontal(alignment) + } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { + containerHelper.alignVertical(alignment) + } } } diff --git a/MVMCoreUI/Molecules/MoleculeContainer.swift b/MVMCoreUI/Molecules/MoleculeContainer.swift new file mode 100644 index 00000000..fa1095db --- /dev/null +++ b/MVMCoreUI/Molecules/MoleculeContainer.swift @@ -0,0 +1,34 @@ +// +// MoleculeContainer.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 12/12/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class MoleculeContainer: Container { + + override public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule) else { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + return + } + if view == nil { + if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { + addSubview(molecule) + containerHelper.constrainView(molecule) + view = molecule + } + } else { + (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) + } + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + } + + open override func reset() { + super.reset() + (view as? MVMCoreUIMoleculeViewProtocol)?.reset?() + } +} diff --git a/MVMCoreUI/Molecules/StandardFooterView.swift b/MVMCoreUI/Molecules/StandardFooterView.swift index 7c9c9282..9620e575 100644 --- a/MVMCoreUI/Molecules/StandardFooterView.swift +++ b/MVMCoreUI/Molecules/StandardFooterView.swift @@ -8,25 +8,14 @@ import UIKit -open class StandardFooterView: ViewConstrainingView { +open class StandardFooterView: MoleculeContainer { open override func setupView() { super.setupView() topMarginPadding = PaddingDefaultVerticalSpacing bottomMarginPadding = PaddingDefaultVerticalSpacing - shouldSetupMoleculeFromJSON = true - updateViewVerticalDefaults = true - updateViewHorizontalDefaults = true } - open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - - // This molecule will by default handle margins. - (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false) - (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false) - } - - public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { if let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) { return height + PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing } diff --git a/MVMCoreUI/Molecules/StandardHeaderView.swift b/MVMCoreUI/Molecules/StandardHeaderView.swift index aa2b52af..23cf6c17 100644 --- a/MVMCoreUI/Molecules/StandardHeaderView.swift +++ b/MVMCoreUI/Molecules/StandardHeaderView.swift @@ -8,7 +8,7 @@ import UIKit -public class StandardHeaderView: ViewConstrainingView { +public class StandardHeaderView: MoleculeContainer { var line: Line? // MARK: - MVMCoreViewProtocol @@ -19,9 +19,6 @@ public class StandardHeaderView: ViewConstrainingView { public override func setupView() { super.setupView() - shouldSetupMoleculeFromJSON = true - updateViewVerticalDefaults = true - updateViewHorizontalDefaults = true topMarginPadding = PaddingDefaultVerticalSpacing bottomMarginPadding = PaddingDefaultVerticalSpacing @@ -38,11 +35,6 @@ public class StandardHeaderView: ViewConstrainingView { // MARK: - MVMCoreUIMoleculeViewProtocol open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - - // This molecule will by default handle margins. - (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false) - (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false) - if let separatorJSON = json?.optionalDictionaryForKey("separator") { line?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData) } @@ -50,12 +42,12 @@ public class StandardHeaderView: ViewConstrainingView { open override func reset() { super.reset() + line?.style = .heavy topMarginPadding = PaddingDefaultVerticalSpacing bottomMarginPadding = PaddingDefaultVerticalSpacing - line?.style = .heavy } - public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { if let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) { return height + PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing } From 3dd9decfed16043a881a248d00cdc6c3dbc61b40 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 12 Dec 2019 14:53:52 -0500 Subject: [PATCH 11/25] Removed height constraint. This class will expect text to function properly. --- MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 404764fe..7d60d1bf 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -44,8 +44,6 @@ guard subviews.isEmpty else { return } - translatesAutoresizingMaskIntoConstraints = false - addSubview(checkbox) addSubview(label) @@ -66,12 +64,10 @@ label.leadingAnchor.constraint(equalTo: checkbox.trailingAnchor, constant: PaddingTwo).isActive = true layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true - let bottomLabelConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: label.bottomAnchor) + bottomLabelConstraint.priority = .defaultLow bottomLabelConstraint.isActive = true - label.heightAnchor.constraint(greaterThanOrEqualToConstant: 15).isActive = true - alignCheckbox(.center) } From 7f01bc286c46b0d739db6bb04b0a706a7dbb88b0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 13 Dec 2019 17:07:10 -0500 Subject: [PATCH 12/25] stack item as container --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Containers/Container.swift | 32 ++++-- MVMCoreUI/Molecules/Items/StackItem.swift | 56 ++++++++++ MVMCoreUI/Molecules/MoleculeContainer.swift | 9 +- MVMCoreUI/Molecules/StandardFooterView.swift | 6 ++ .../EyebrowHeadlineBodyLink.swift | 12 +-- MVMCoreUI/Organisms/MoleculeStackView.swift | 101 +++++++----------- .../Templates/MoleculeStackTemplate.swift | 1 + 8 files changed, 137 insertions(+), 84 deletions(-) create mode 100644 MVMCoreUI/Molecules/Items/StackItem.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 73ecaabf..e8c26f4c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -199,6 +199,7 @@ D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; }; D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; }; D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; }; + D2FB151D23A40F1500C20E10 /* StackItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151C23A40F1500C20E10 /* StackItem.swift */; }; DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; @@ -404,6 +405,7 @@ D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = ""; }; D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = ""; }; + D2FB151C23A40F1500C20E10 /* StackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackItem.swift; sourceTree = ""; }; DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = ""; }; DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; @@ -524,6 +526,7 @@ D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */, D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */, D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */, + D2FB151C23A40F1500C20E10 /* StackItem.swift */, ); path = Items; sourceTree = ""; @@ -1076,6 +1079,7 @@ D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, + D2FB151D23A40F1500C20E10 /* StackItem.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, 0116A4E5228B19640094F3ED /* RadioButtonModel.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift index 2af6e46a..f5bddcb9 100644 --- a/MVMCoreUI/Containers/Container.swift +++ b/MVMCoreUI/Containers/Container.swift @@ -9,10 +9,10 @@ import UIKit public protocol ContainerModelProtocol { - var horizontalAlignment: UIStackView.Alignment { get set } - var verticalAlignment: UIStackView.Alignment { get set } - var useHorizontalMargins: Bool { get set } - var useVerticalMargins: Bool { get set } + var horizontalAlignment: UIStackView.Alignment? { get set } + var verticalAlignment: UIStackView.Alignment? { get set } + var useHorizontalMargins: Bool? { get set } + var useVerticalMargins: Bool? { get set } } public class ContainerHelper: NSObject { @@ -146,8 +146,12 @@ public class ContainerHelper: NSObject { } func set(with model: ContainerModelProtocol) { - alignHorizontal(model.horizontalAlignment) - alignVertical(model.verticalAlignment) + if let horizontalAlignment = model.horizontalAlignment { + alignHorizontal(horizontalAlignment) + } + if let verticalAlignment = model.verticalAlignment { + alignVertical(verticalAlignment) + } } static func getAlignment(for string: String) -> UIStackView.Alignment? { @@ -188,6 +192,17 @@ public extension Container { super.setupView() backgroundColor = .clear } + + func addAndContain(_ view: UIView) { + addSubview(view) + containerHelper.constrainView(view) + self.view = view + } + + convenience init(andContain view: UIView) { + self.init() + addAndContain(view) + } } // MARK: - MVMCoreUIMoleculeViewProtocol @@ -207,4 +222,9 @@ public extension Container { containerHelper.alignVertical(alignment) } } + + override func reset() { + super.reset() + (view as? MVMCoreUIMoleculeViewProtocol)?.reset?() + } } diff --git a/MVMCoreUI/Molecules/Items/StackItem.swift b/MVMCoreUI/Molecules/Items/StackItem.swift new file mode 100644 index 00000000..72c24204 --- /dev/null +++ b/MVMCoreUI/Molecules/Items/StackItem.swift @@ -0,0 +1,56 @@ +// +// StackItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 12/13/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class StackItemModel: ContainerModelProtocol { + public var view: StackItem + public var spacing: CGFloat? + public var percentage: Int? + public var verticalAlignment: UIStackView.Alignment? + public var horizontalAlignment: UIStackView.Alignment? + public var useHorizontalMargins: Bool? + public var useVerticalMargins: Bool? + public var gone = false + + init(with view: StackItem) { + self.view = view + view.model = self + } + + init(with view: StackItem, json: [AnyHashable: Any]?) { + self.view = view + view.model = self + update(with: json) + } + + func update(with json: [AnyHashable: Any]?) { + gone = json?.boolForKey("gone") ?? (json == nil) + spacing = json?.optionalCGFloatForKey("spacing") + percentage = json?["percent"] as? Int + if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment") { + horizontalAlignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) + } else { + horizontalAlignment = nil + } + + if let verticalAlignmentString = json?.optionalStringForKey("verticalAlignment") { + verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString) + } else { + verticalAlignment = nil + } + + useHorizontalMargins = json?.optionalBoolForKey("useHorizontalMargins") ?? false + useVerticalMargins = json?.optionalBoolForKey("useVerticalMargins") ?? false + } +} + +open class StackItem: MoleculeContainer { + + +} diff --git a/MVMCoreUI/Molecules/MoleculeContainer.swift b/MVMCoreUI/Molecules/MoleculeContainer.swift index fa1095db..14a5bb4a 100644 --- a/MVMCoreUI/Molecules/MoleculeContainer.swift +++ b/MVMCoreUI/Molecules/MoleculeContainer.swift @@ -17,18 +17,11 @@ open class MoleculeContainer: Container { } if view == nil { if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { - addSubview(molecule) - containerHelper.constrainView(molecule) - view = molecule + addAndContain(molecule) } } else { (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) } super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } - - open override func reset() { - super.reset() - (view as? MVMCoreUIMoleculeViewProtocol)?.reset?() - } } diff --git a/MVMCoreUI/Molecules/StandardFooterView.swift b/MVMCoreUI/Molecules/StandardFooterView.swift index 9620e575..a83611cc 100644 --- a/MVMCoreUI/Molecules/StandardFooterView.swift +++ b/MVMCoreUI/Molecules/StandardFooterView.swift @@ -21,4 +21,10 @@ open class StandardFooterView: MoleculeContainer { } return 42 } + + open override func reset() { + super.reset() + topMarginPadding = PaddingDefaultVerticalSpacing + bottomMarginPadding = PaddingDefaultVerticalSpacing + } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index a7d96a34..5bec3a5c 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -22,15 +22,14 @@ import UIKit return } stack.spacing = 0 - stack.updateViewHorizontalDefaults = false addSubview(stack) pinView(toSuperView: stack) - stack.addStackItem(StackItem(with: eyebrow), lastItem: false) - stack.addStackItem(StackItem(with: headline), lastItem: false) - stack.addStackItem(StackItem(with: body), lastItem: false) + stack.addStackItem(StackItemModel(with: StackItem(andContain: eyebrow)), lastItem: false) + stack.addStackItem(StackItemModel(with: StackItem(andContain: headline)), lastItem: false) + stack.addStackItem(StackItemModel(with: StackItem(andContain: body)), lastItem: false) // To visually take into account the extra padding in the intrinsic content of a button. - let stackItem = StackItem(with: link) + let stackItem = StackItemModel(with: StackItem(andContain: link)) stackItem.spacing = -6 stack.addStackItem(stackItem, lastItem: true) } @@ -38,6 +37,8 @@ import UIKit open override func updateView(_ size: CGFloat) { super.updateView(size) stack.updateView(size) + stack.directionalLayoutMargins.leading = 0 + stack.directionalLayoutMargins.trailing = 0 } // MARK: - MVMCoreUIMoleculeViewProtocol @@ -58,7 +59,6 @@ import UIKit super.reset() stack.reset() stack.spacing = 0 - stack.updateViewHorizontalDefaults = false eyebrow.styleB3(true) headline.styleB1(true) body.styleB2(true) diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index dc7cc81e..892243c8 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -8,47 +8,13 @@ import UIKit -public class StackItem { - var view: UIView - var spacing: CGFloat? - var percentage: Int? - var verticalAlignment: UIStackView.Alignment? - var horizontalAlignment: UIStackView.Alignment? - var gone = false - - init(with view: UIView) { - self.view = view - } - - init(with view: UIView, json: [AnyHashable: Any]?) { - self.view = view - update(with: json) - } - - func update(with json: [AnyHashable: Any]?) { - gone = json?.boolForKey("gone") ?? (json == nil) - spacing = json?.optionalCGFloatForKey("spacing") - percentage = json?["percent"] as? Int - if let alignment = json?.stringOptionalWithChainOfKeysOrIndexes([KeyMolecule,"verticalAlignment"]) { - verticalAlignment = ViewConstrainingView.getAlignmentFor(alignment, defaultAlignment: .fill) - } else { - verticalAlignment = nil - } - if let alignment = json?.stringOptionalWithChainOfKeysOrIndexes([KeyMolecule,"horizontalAlignment"]) { - horizontalAlignment = ViewConstrainingView.getAlignmentFor(alignment, defaultAlignment: .fill) - } else { - horizontalAlignment = nil - } - } -} - -public class MoleculeStackView: ViewConstrainingView { +open class MoleculeStackView: Container { var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() - var items: [StackItem] = [] + var items: [StackItemModel] = [] var useStackSpacingBeforeFirstItem = false - private var moleculesShouldSetHorizontalMargins = false - private var moleculesShouldSetVerticalMargins = false + var moleculesShouldSetHorizontalMargins = false + var moleculesShouldSetVerticalMargins = false /// For setting the direction of the stack var axis: NSLayoutConstraint.Axis = .vertical { @@ -97,6 +63,10 @@ public class MoleculeStackView: ViewConstrainingView { } // MARK: - Inits + public override init() { + super.init() + } + public override init(frame: CGRect) { super.init(frame: frame) } @@ -117,19 +87,20 @@ public class MoleculeStackView: ViewConstrainingView { return } MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) - updateViewHorizontalDefaults = true translatesAutoresizingMaskIntoConstraints = false backgroundColor = .clear addSubview(contentView) - pinView(toSuperView: 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 for item in items { - (item.view as? MVMCoreViewProtocol)?.updateView(size) + item.view.updateView(size) } } @@ -137,11 +108,8 @@ public class MoleculeStackView: ViewConstrainingView { public override func reset() { super.reset() backgroundColor = .clear - updateViewHorizontalDefaults = true for item in items { - if let view = item.view as? MVMCoreUIMoleculeViewProtocol { - view.reset?() - } + item.view.reset() } } @@ -151,7 +119,7 @@ public class MoleculeStackView: ViewConstrainingView { removeAllItemViews() // If the items in the stack are the same, just update previous items instead of re-allocating. - var items: [StackItem]? + var items: [StackItemModel]? if MoleculeStackView.name(forReuse: previousJSON, delegateObject: delegateObject) == MoleculeStackView.name(forReuse: json, delegateObject: delegateObject) { items = self.items } @@ -169,22 +137,28 @@ public class MoleculeStackView: ViewConstrainingView { for (index, map) in molecules.enumerated() { if let moleculeJSON = map.optionalDictionaryForKey(KeyMolecule) { var view: UIView? + var stackItemModel: StackItemModel if let item = items?[index] { + stackItemModel = item item.update(with: map) view = item.view (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: nil) addStackItem(item, lastItem: index == molecules.count - 1) - } else if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) { - view = molecule - addStackItem(StackItem(with: molecule, json: map), lastItem: index == molecules.count - 1) + } else { + let stackItem = StackItem() + stackItem.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) + view = stackItem + stackItemModel = StackItemModel(with: stackItem, json: map) + addStackItem(stackItemModel, lastItem: index == molecules.count - 1) } - (view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins) - (view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins) + + stackItemModel.useHorizontalMargins = moleculesShouldSetHorizontalMargins + stackItemModel.useVerticalMargins = moleculesShouldSetVerticalMargins } } } - public override class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { + 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(KeyMolecules) else { return "stack<>" @@ -199,7 +173,7 @@ public class MoleculeStackView: ViewConstrainingView { return name } - public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { guard let items = json?.optionalArrayForKey(KeyMolecules) else { return 0 } @@ -221,7 +195,7 @@ public class MoleculeStackView: ViewConstrainingView { return estimatedHeight } - public override class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { guard let items = json?.optionalArrayForKey(KeyMolecules) else { return nil } @@ -237,11 +211,11 @@ public class MoleculeStackView: ViewConstrainingView { // MARK: - Adding to stack /// Adds the view to the stack. func addView(_ view: UIView, lastItem: Bool) { - addStackItem(StackItem(with: view), lastItem: lastItem) + addStackItem(StackItemModel(with: StackItem(andContain: view)), lastItem: lastItem) } /// Adds the stack item to the stack. - func addStackItem(_ stackItem: StackItem, lastItem: Bool) { + func addStackItem(_ stackItem: StackItemModel, lastItem: Bool) { guard !stackItem.gone else { items.append(stackItem) return @@ -251,12 +225,11 @@ public class MoleculeStackView: ViewConstrainingView { view.translatesAutoresizingMaskIntoConstraints = false let spacing = stackItem.spacing ?? self.spacing - if let view = view as? MVMCoreUIViewConstrainingProtocol { - let verticalAlignment = stackItem.verticalAlignment ?? (stackItem.percentage == nil && axis == .vertical ? .fill : (axis == .vertical ? .leading : .center)) - let horizontalAlignment = stackItem.horizontalAlignment ?? view.alignment?() ?? (axis == .vertical || stackItem.percentage == nil ? .fill : .leading) - view.alignHorizontal?(horizontalAlignment) - view.alignVertical?(verticalAlignment) - } + let verticalAlignment = stackItem.verticalAlignment ?? (stackItem.percentage == nil && axis == .vertical ? .fill : (axis == .vertical ? .leading : .center)) + let horizontalAlignment = stackItem.horizontalAlignment ?? (view.view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() ?? (axis == .vertical || stackItem.percentage == nil ? .fill : .leading) + view.containerHelper.alignHorizontal(horizontalAlignment) + view.containerHelper.alignVertical(verticalAlignment) + let first = items.first { !$0.gone } == nil if axis == .vertical { if first { @@ -295,10 +268,10 @@ public class MoleculeStackView: ViewConstrainingView { items.append(stackItem) } - func setWithStackItems(_ items: [StackItem]) { + func setWithStackItems(_ items: [StackItemModel]) { removeAllItemViews() self.items.removeAll() - var previousPresentItem: StackItem? = nil + var previousPresentItem: StackItemModel? = nil for item in items { if !item.gone { previousPresentItem = item diff --git a/MVMCoreUI/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Templates/MoleculeStackTemplate.swift index d6f78b05..b0881321 100644 --- a/MVMCoreUI/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeStackTemplate.swift @@ -42,6 +42,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController { } let stack = MoleculeStackView(frame: .zero) stack.useStackSpacingBeforeFirstItem = true + stack.moleculesShouldSetHorizontalMargins = true stack.setWithJSON(moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) return stack } From 7926a8579c78bd71bd89f85afaf91e832bb18c77 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 16 Dec 2019 10:50:18 -0500 Subject: [PATCH 13/25] Comment fixes --- MVMCoreUI/Molecules/Items/StackItem.swift | 4 ++-- .../VerticalCombinationViews/EyebrowHeadlineBodyLink.swift | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/StackItem.swift b/MVMCoreUI/Molecules/Items/StackItem.swift index 72c24204..6ee5ae88 100644 --- a/MVMCoreUI/Molecules/Items/StackItem.swift +++ b/MVMCoreUI/Molecules/Items/StackItem.swift @@ -14,8 +14,8 @@ open class StackItemModel: ContainerModelProtocol { public var percentage: Int? public var verticalAlignment: UIStackView.Alignment? public var horizontalAlignment: UIStackView.Alignment? - public var useHorizontalMargins: Bool? - public var useVerticalMargins: Bool? + public var useHorizontalMargins: Bool? = false + public var useVerticalMargins: Bool? = false public var gone = false init(with view: StackItem) { diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index 5bec3a5c..869bd23a 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -37,8 +37,6 @@ import UIKit open override func updateView(_ size: CGFloat) { super.updateView(size) stack.updateView(size) - stack.directionalLayoutMargins.leading = 0 - stack.directionalLayoutMargins.trailing = 0 } // MARK: - MVMCoreUIMoleculeViewProtocol From f610264327c7e6389b5ed70edb830520d930cee2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 16 Dec 2019 11:19:30 -0500 Subject: [PATCH 14/25] alignment updates --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 2 +- MVMCoreUI/Atoms/Buttons/MFTextButton.m | 2 +- MVMCoreUI/Atoms/Views/CaretView.swift | 2 +- .../Atoms/Views/CheckboxWithLabelView.swift | 2 +- MVMCoreUI/Atoms/Views/Label.swift | 2 +- MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m | 2 +- MVMCoreUI/Containers/Container.swift | 2 +- MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m | 2 +- MVMCoreUI/Organisms/MoleculeStackView.swift | 36 +++++++++---------- 9 files changed, 25 insertions(+), 27 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index b01d2758..6c9de088 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -136,7 +136,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI return true } - open func alignment() -> UIStackView.Alignment { + open func horizontalAlignment() -> UIStackView.Alignment { return UIStackView.Alignment.leading; } diff --git a/MVMCoreUI/Atoms/Buttons/MFTextButton.m b/MVMCoreUI/Atoms/Buttons/MFTextButton.m index e1a6c504..a0ee6ca7 100644 --- a/MVMCoreUI/Atoms/Buttons/MFTextButton.m +++ b/MVMCoreUI/Atoms/Buttons/MFTextButton.m @@ -156,7 +156,7 @@ return YES; } -- (UIStackViewAlignment)alignment { +- (UIStackViewAlignment)horizontalAlignment { return UIStackViewAlignmentLeading; } diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index b68d0535..9b500cdc 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -131,7 +131,7 @@ extension CaretView: MVMCoreUIViewConstrainingProtocol { return true } - open func alignment() -> UIStackView.Alignment { + open func horizontalAlignment() -> UIStackView.Alignment { return UIStackView.Alignment.leading; } } diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index f148863b..7ce1104e 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -165,7 +165,7 @@ extension CheckboxWithLabelView { layoutIfNeeded() } - override open func alignment() -> UIStackView.Alignment { + override open func horizontalAlignment() -> UIStackView.Alignment { return .leading } diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 99a28463..56a0c38b 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -598,7 +598,7 @@ extension Label { return true } - public func alignment() -> UIStackView.Alignment { + public func horizontalAlignment() -> UIStackView.Alignment { return .leading } diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m index 8ec71241..33874a8d 100644 --- a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m @@ -193,7 +193,7 @@ const CGFloat SwitchShakeIntensity = 2; return YES; } -- (UIStackViewAlignment)alignment { +- (UIStackViewAlignment)horizontalAlignment { return UIStackViewAlignmentTrailing; } diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift index f5bddcb9..5b565683 100644 --- a/MVMCoreUI/Containers/Container.swift +++ b/MVMCoreUI/Containers/Container.swift @@ -217,7 +217,7 @@ public extension Container { } if let verticalAlignmentString = json?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { - containerHelper.alignHorizontal(alignment) + containerHelper.alignVertical(alignment) } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { containerHelper.alignVertical(alignment) } diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m index 54358ebe..40fa987f 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m @@ -54,7 +54,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0; return YES; } -- (UIStackViewAlignment)alignment { +- (UIStackViewAlignment)horizontalAlignment { return UIStackViewAlignmentLeading; } diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index 892243c8..4b37b66d 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -135,26 +135,24 @@ open class MoleculeStackView: Container { // Adds the molecules and sets the json. for (index, map) in molecules.enumerated() { - if let moleculeJSON = map.optionalDictionaryForKey(KeyMolecule) { - var view: UIView? - var stackItemModel: StackItemModel - if let item = items?[index] { - stackItemModel = item - item.update(with: map) - view = item.view - (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: nil) - addStackItem(item, lastItem: index == molecules.count - 1) - } else { - let stackItem = StackItem() - stackItem.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) - view = stackItem - stackItemModel = StackItemModel(with: stackItem, json: map) - addStackItem(stackItemModel, lastItem: index == molecules.count - 1) - } - - stackItemModel.useHorizontalMargins = moleculesShouldSetHorizontalMargins - stackItemModel.useVerticalMargins = moleculesShouldSetVerticalMargins + var view: UIView? + var stackItemModel: StackItemModel + if let item = items?[index] { + stackItemModel = item + item.update(with: map) + view = item.view + (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) + addStackItem(item, lastItem: index == molecules.count - 1) + } else { + let stackItem = StackItem() + stackItem.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) + view = stackItem + stackItemModel = StackItemModel(with: stackItem, json: map) + addStackItem(stackItemModel, lastItem: index == molecules.count - 1) } + + stackItemModel.useHorizontalMargins = moleculesShouldSetHorizontalMargins + stackItemModel.useVerticalMargins = moleculesShouldSetVerticalMargins } } From 092dfd6ad0f50c8f47e14894187e101315b5779c Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 16 Dec 2019 13:40:04 -0500 Subject: [PATCH 15/25] List item updates --- MVMCoreUI/Atoms/Buttons/PrimaryButton.m | 5 ++++ MVMCoreUI/Containers/Container.swift | 29 +++++++++++-------- .../Items/MoleculeTableViewCell.swift | 17 ++++++++--- MVMCoreUI/Molecules/Items/TableViewCell.swift | 22 ++++---------- .../MVMCoreUIMoleculeMappingObject.m | 2 +- 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m index 3b1802e5..074facb4 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m @@ -664,6 +664,7 @@ } - (void)setAsMolecule { + self.translatesAutoresizingMaskIntoConstraints = false; [self setAsStandardCustom]; } @@ -713,6 +714,10 @@ [self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData]; } +- (UIStackViewAlignment)horizontalAlignment { + return UIStackViewAlignmentCenter; +} + #pragma mark - Handling Validations - (void)setEnabledByValidity { diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift index 5b565683..0b0c4bd5 100644 --- a/MVMCoreUI/Containers/Container.swift +++ b/MVMCoreUI/Containers/Container.swift @@ -168,6 +168,20 @@ public class ContainerHelper: NSObject { return nil } } + + func set(with JSON: [AnyHashable: Any]?, for contained: UIView) { + if let horizontalAlignmentString = JSON?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { + alignHorizontal(alignment) + } else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { + alignHorizontal(alignment) + } + + if let verticalAlignmentString = JSON?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { + alignVertical(alignment) + } else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { + alignVertical(alignment) + } + } } open class Container: View { @@ -194,6 +208,7 @@ public extension Container { } func addAndContain(_ view: UIView) { + view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) containerHelper.constrainView(view) self.view = view @@ -209,18 +224,8 @@ public extension Container { public extension Container { override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - - if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { - containerHelper.alignHorizontal(alignment) - } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() { - containerHelper.alignHorizontal(alignment) - } - - if let verticalAlignmentString = json?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { - containerHelper.alignVertical(alignment) - } else if let alignment = (view as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() { - containerHelper.alignVertical(alignment) - } + guard let view = view else { return } + containerHelper.set(with: json, for: view) } override func reset() { diff --git a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift index 4769b7e5..7cd3a900 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift @@ -11,11 +11,20 @@ import UIKit @objcMembers open class MoleculeTableViewCell: TableViewCell { // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) + { + guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule) else { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + return + } + if molecule == nil { + if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { + addMolecule(moleculeView) + } + } else { + molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) + } super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - - guard molecule == nil, let json = json, let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule), let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) else { return } - addMolecule(moleculeView) } public override class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index 13faeb42..0293958f 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -11,7 +11,8 @@ import UIKit @objcMembers open class TableViewCell: UITableViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol { open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)? open var json: [AnyHashable: Any]? - + public let containerHelper = ContainerHelper() + // In updateView, will set padding to default. open var updateViewHorizontalDefaults = true @@ -78,14 +79,7 @@ import UIKit /// Adds the molecule to the view. open func addMolecule(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { contentView.addSubview(molecule) - let standardConstraints = (molecule as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: molecule, useMargins: standardConstraints).values)) - - // This molecule will by default handle margins. - if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { - castView.shouldSetHorizontalMargins?(false) - castView.shouldSetVerticalMargins?(false) - } + containerHelper.constrainView(molecule) self.molecule = molecule } @@ -176,14 +170,8 @@ import UIKit bottomSeparatorView?.setWithJSON(separator, delegateObject: delegateObject, additionalData: additionalData) } - guard let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule) else { return } - molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) - - // This molecule will by default handle margins. - if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { - castView.shouldSetHorizontalMargins?(false) - castView.shouldSetVerticalMargins?(false) - } + guard let molecule = molecule else { return } + containerHelper.set(with: json, for: molecule) } public func reset() { diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 51a07225..9db7822d 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -27,7 +27,7 @@ mapping = [@{ @"label": Label.class, @"line": Line.class, - @"button": ButtonView.class, + @"button": PrimaryButton.class, @"textButton": MFTextButton.class, @"header": StandardHeaderView.class, @"moleculeStack": MoleculeStackView.class, From dc8910c61d232f3ba2edfa4cf6e80b95b67b8eff Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 16 Dec 2019 13:54:52 -0500 Subject: [PATCH 16/25] add height constraint --- MVMCoreUI/Atoms/Buttons/PrimaryButton.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m index 074facb4..2bc9e026 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m @@ -665,6 +665,7 @@ - (void)setAsMolecule { self.translatesAutoresizingMaskIntoConstraints = false; + [self pinHeight]; [self setAsStandardCustom]; } From 03f64b0875af7a28d009764a88aa43936890d816 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 17 Dec 2019 09:38:51 -0500 Subject: [PATCH 17/25] Module Molecule update to Container --- MVMCoreUI/Containers/Container.swift | 4 ++ MVMCoreUI/Molecules/ModuleMolecule.swift | 67 ++++++------------------ 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/MVMCoreUI/Containers/Container.swift b/MVMCoreUI/Containers/Container.swift index 0b0c4bd5..069cd9e3 100644 --- a/MVMCoreUI/Containers/Container.swift +++ b/MVMCoreUI/Containers/Container.swift @@ -232,4 +232,8 @@ public extension Container { super.reset() (view as? MVMCoreUIMoleculeViewProtocol)?.reset?() } + + func setAsMolecule() { + (view as? MVMCoreUIMoleculeViewProtocol)?.setAsMolecule?() + } } diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index 77acc007..f54e7171 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -8,13 +8,20 @@ import UIKit -open class ModuleMolecule: ViewConstrainingView { +struct ModuleMoleculeModel: ContainerModelProtocol { + var horizontalAlignment: UIStackView.Alignment? = .fill + var verticalAlignment: UIStackView.Alignment? = .fill + var useHorizontalMargins: Bool? = false + var useVerticalMargins: Bool? = false +} + +open class ModuleMolecule: Container { open var moduleMolecule: (UIView & MVMCoreUIMoleculeViewProtocol)? - - open override func updateView(_ size: CGFloat) { - super.updateView(size) - moduleMolecule?.updateView(size) + + public override func setupView() { + super.setupView() + model = ModuleMoleculeModel() } // MARK: - MVMCoreUIMoleculeViewProtocol @@ -27,34 +34,15 @@ open class ModuleMolecule: ViewConstrainingView { } if moduleMolecule == nil { - if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: module, delegateObject: delegateObject, constrainIfNeeded: true) { - addSubview(moleculeView) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values)) - moduleMolecule = moleculeView - - isAccessibilityElement = false - if moleculeView.accessibilityElements != nil { - accessibilityElements = moleculeView.accessibilityElements - } else { - accessibilityElements = [moleculeView] - } + if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: module, delegateObject: delegateObject, constrainIfNeeded: false) { + addAndContain(moleculeView) } } else { moduleMolecule?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData) } } - open override func setAsMolecule() { - super.setAsMolecule() - moduleMolecule?.setAsMolecule?() - } - - open override func reset() { - super.reset() - moduleMolecule?.reset?() - } - - public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { guard let moduleName = json?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else { // Critical error return 0 @@ -62,7 +50,7 @@ open class ModuleMolecule: ViewConstrainingView { return MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.estimatedHeight?(forRow: module, delegateObject: delegateObject) ?? 0 } - public override class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { + public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let moduleName = molecule?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else { // Critical error return "moduleMolecule<>" @@ -70,7 +58,7 @@ open class ModuleMolecule: ViewConstrainingView { return "moduleMolecule<" + (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.name?(forReuse: module, delegateObject: delegateObject) ?? module.stringForkey(KeyMoleculeName)) + ">" } - public override class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { let moduleName = json?.optionalStringForKey("moduleName") if moduleName == nil || delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) == nil { if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { @@ -83,25 +71,4 @@ open class ModuleMolecule: ViewConstrainingView { } return nil } - - // MARK: - MVMCoreUIViewConstrainingProtocol - open override func useStandardConstraints() -> Bool { - return (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true - } - - open override func alignHorizontal(_ alignment: UIStackView.Alignment) { - (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.alignHorizontal?(alignment) - } - - open override func alignVertical(_ alignment: UIStackView.Alignment) { - (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.alignVertical?(alignment) - } - - open override func shouldSetHorizontalMargins(_ shouldSet: Bool) { - (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(shouldSet) - } - - open override func shouldSetVerticalMargins(_ shouldSet: Bool) { - (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(shouldSet) - } } From cd9e63b992ca26c87333818a9cc51cd7252f6a4f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 17 Dec 2019 09:51:49 -0500 Subject: [PATCH 18/25] carousel to container --- .../Items/MoleculeCollectionViewCell.swift | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift index 75249f7d..35b3ed04 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift @@ -11,7 +11,8 @@ import UIKit open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol { open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)? open var json: [AnyHashable: Any]? - + public let containerHelper = ContainerHelper() + // In updateView, will set padding to default. open var updateViewHorizontalDefaults = true open var updateViewVerticalDefaults = true @@ -91,21 +92,19 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi return } if molecule == nil { - if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) { + if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { contentView.insertSubview(moleculeView, at: 0) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: true).values)) + containerHelper.constrainView(moleculeView) molecule = moleculeView } } else { molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) } - // This molecule will handle spacing by default. - if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { - castView.shouldSetHorizontalMargins?(false) - castView.shouldSetVerticalMargins?(false) - } + + guard let molecule = molecule else { return } + containerHelper.set(with: json, for: molecule) - accessibilityElements = molecule?.subviews + accessibilityElements = molecule.subviews } public func reset() { From 95c528b658d956c898cbe62e93fe84f593aaca17 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 18 Dec 2019 21:20:58 +0530 Subject: [PATCH 19/25] progress bar percentage is been treated as Double for two decimal places(Like 54.17) in iOS JSON object, due to that progress percentage is not shown, where as working on Android. So, changing Float to Double. --- MVMCoreUI/Atoms/Views/ProgressBar.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atoms/Views/ProgressBar.swift index 1aecd537..affd6761 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBar.swift @@ -54,8 +54,8 @@ import Foundation if let thickness = json?.optionalCGFloatForKey("thickness") { self.thickness = thickness } - if let percentage = json?["percent"] as? Float { - progress = percentage/100.0 + if let percentage = json?["percent"] as? Double { + progress = Float(percentage/100.0) } if let progressColor = json?.optionalStringForKey("progressColor") { progressTintColor = UIColor.mfGet(forHex: progressColor) From 09a9a6577d40ad95faec605b3c50326345578543 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 18 Dec 2019 21:36:50 +0530 Subject: [PATCH 20/25] Adding new style sectionFooter for listItem molecule. There are two places in MVA 3.0, where we need 24 pixel spacing on top, zero spacing on bottom and no separator. --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index 2c14f9be..bab1701f 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -48,6 +48,8 @@ import UIKit styleStandard() case "header": styleHeader() + case "sectionFooter": + styleFooter() case "none": styleNone() default: break @@ -68,6 +70,13 @@ import UIKit bottomSeparatorView?.style = .thin } + open func styleFooter() { + topMarginPadding = 24 + bottomMarginPadding = 0 + topSeparatorView?.style = .none + bottomSeparatorView?.style = .none + } + open func styleNone() { topMarginPadding = 0 bottomMarginPadding = 0 From aff4b7536839d340a56fb4aee9cf39a47901b9bb Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 18 Dec 2019 22:28:22 +0530 Subject: [PATCH 21/25] Changing to CGFloat, instead of Double as per feedback provided by Ryan. Root Cause: Swift was treating it as Double, instead of Float. --- MVMCoreUI/Atoms/Views/ProgressBar.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atoms/Views/ProgressBar.swift index affd6761..1f75b1d0 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBar.swift @@ -54,7 +54,7 @@ import Foundation if let thickness = json?.optionalCGFloatForKey("thickness") { self.thickness = thickness } - if let percentage = json?["percent"] as? Double { + if let percentage = json?["percent"] as? CGFloat { progress = Float(percentage/100.0) } if let progressColor = json?.optionalStringForKey("progressColor") { From eec15fc65ecf75a3c877553233eb4d327a24f38b Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Thu, 19 Dec 2019 19:21:49 +0530 Subject: [PATCH 22/25] added comment as per Scott feedback --- MVMCoreUI/Atoms/Views/ProgressBar.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atoms/Views/ProgressBar.swift index 1f75b1d0..c73c77b4 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBar.swift @@ -54,6 +54,7 @@ import Foundation if let thickness = json?.optionalCGFloatForKey("thickness") { self.thickness = thickness } + // as? Float returns nil, apple defect. if let percentage = json?["percent"] as? CGFloat { progress = Float(percentage/100.0) } From dcd0268c5b1c2ae5fb072f21152a10326cef2d3f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 19 Dec 2019 10:14:57 -0500 Subject: [PATCH 23/25] fix --- MVMCoreUI/Molecules/ModuleMolecule.swift | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index f54e7171..66e18d47 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -16,9 +16,6 @@ struct ModuleMoleculeModel: ContainerModelProtocol { } open class ModuleMolecule: Container { - - open var moduleMolecule: (UIView & MVMCoreUIMoleculeViewProtocol)? - public override func setupView() { super.setupView() model = ModuleMoleculeModel() @@ -33,12 +30,12 @@ open class ModuleMolecule: Container { return } - if moduleMolecule == nil { + if view == nil { if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: module, delegateObject: delegateObject, constrainIfNeeded: false) { addAndContain(moleculeView) } } else { - moduleMolecule?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData) + (view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData) } } From 9e5ccb01a795f59c1f9b48ebfac997ba3b90e8d5 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 19 Dec 2019 11:09:18 -0500 Subject: [PATCH 24/25] removed unused func. --- MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 7d60d1bf..7cd7d1a7 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -137,13 +137,6 @@ extension CheckboxWithLabelView { layoutIfNeeded() } - open func resetConstraints() { - - checkboxCenterYConstraint?.isActive = false - checkboxBottomConstraint?.isActive = false - checkboxTopConstraint?.isActive = false - } - open override func reset() { super.reset() From 6c9fede0b9d94db0b8fa27a16b2f7d6bef9775d3 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 19 Dec 2019 11:12:59 -0500 Subject: [PATCH 25/25] improved reset. --- MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift index 7cd7d1a7..6991adef 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxWithLabelView.swift @@ -142,6 +142,7 @@ extension CheckboxWithLabelView { label.text = "" checkbox.reset() + alignCheckbox(.center) } override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {