From 392ab144acac53120803230765bb70662fd9c41f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 25 Nov 2019 16:01:43 -0500 Subject: [PATCH 01/59] small fixes --- MVMCoreUI/Atoms/Views/GraphView.swift | 4 ++-- MVMCoreUI/Atoms/Views/Line.swift | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/GraphView.swift b/MVMCoreUI/Atoms/Views/GraphView.swift index eb2b2099..6ef3132c 100644 --- a/MVMCoreUI/Atoms/Views/GraphView.swift +++ b/MVMCoreUI/Atoms/Views/GraphView.swift @@ -93,8 +93,8 @@ public struct GraphObject { mutating func updateSize() { switch size { case .small: - diameter = MFSizeObject(standardSize: 24)?.getValueBasedOnApplicationWidth() ?? 24 - lineWidth = MFSizeObject(standardSize: 5)?.getValueBasedOnApplicationWidth() ?? 5 + diameter = MFSizeObject(standardSize: 20)?.getValueBasedOnApplicationWidth() ?? 20 + lineWidth = MFSizeObject(standardSize: 4)?.getValueBasedOnApplicationWidth() ?? 4 break case .medium: diameter = MFSizeObject(standardSize: 100)?.getValueBasedOnApplicationWidth() ?? 100 diff --git a/MVMCoreUI/Atoms/Views/Line.swift b/MVMCoreUI/Atoms/Views/Line.swift index f7a81ac5..d5f4f4b6 100644 --- a/MVMCoreUI/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atoms/Views/Line.swift @@ -38,8 +38,6 @@ import UIKit case .none: heightConstraint?.constant = 0 } - setNeedsLayout() - layoutIfNeeded() } } From 63556707bc66928585b966a3287932b9aac2fd5f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 Nov 2019 13:49:01 -0500 Subject: [PATCH 02/59] temporary dropdown molecule label reuse font fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ MVMCoreUI/Atoms/TextFields/MFTextField.h | 1 + MVMCoreUI/Atoms/TextFields/MFTextField.m | 1 + MVMCoreUI/Atoms/TextFields/MFTextField.xib | 9 +- MVMCoreUI/Atoms/Views/DropDown.swift | 55 ++++++++++++ MVMCoreUI/Atoms/Views/Label.swift | 28 +++--- MVMCoreUI/Atoms/Views/ViewConstrainingView.m | 1 - .../Items/DropDownFilterTableViewCell.swift | 70 +++++++++++++++ .../MVMCoreUIMoleculeMappingObject.m | 10 ++- MVMCoreUI/Styles/MFStyler.h | 10 +++ MVMCoreUI/Styles/MFStyler.m | 90 +++++++++++++------ 11 files changed, 234 insertions(+), 49 deletions(-) create mode 100644 MVMCoreUI/Atoms/Views/DropDown.swift create mode 100644 MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 391e20f5..515e24ee 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ 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, ); }; }; + D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; }; + D268C712238D6699007F2C1C /* DropDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C711238D6699007F2C1C /* DropDown.swift */; }; D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* StandardFooterView.swift */; }; D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; }; D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; }; @@ -246,6 +248,8 @@ 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 = ""; }; + D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = ""; }; + D268C711238D6699007F2C1C /* DropDown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDown.swift; sourceTree = ""; }; D274CA322236A78900B01B62 /* StandardFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardFooterView.swift; sourceTree = ""; }; D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = ""; }; @@ -509,6 +513,7 @@ D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */, D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */, D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */, + D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */, ); path = Items; sourceTree = ""; @@ -752,6 +757,7 @@ D29DF2AD21E7B3A4003B2FB9 /* MFTextView.h */, D29DF2AB21E7B3A4003B2FB9 /* MFTextView.m */, D29DF2AC21E7B3A4003B2FB9 /* MFTextView.xib */, + D268C711238D6699007F2C1C /* DropDown.swift */, D29DF2B121E7B76C003B2FB9 /* MFLoadingSpinner.h */, D29DF2B221E7B76D003B2FB9 /* MFLoadingSpinner.m */, D29DF32321ED0DA2003B2FB9 /* TextButtonView.h */, @@ -1071,6 +1077,7 @@ D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */, D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, 01004F3022721C3800991ECC /* RadioButton.swift in Sources */, + D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */, D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, D29DF25321E6A177003B2FB9 /* MFDigitTextField.m in Sources */, @@ -1154,6 +1161,7 @@ D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, + D268C712238D6699007F2C1C /* DropDown.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField.h b/MVMCoreUI/Atoms/TextFields/MFTextField.h index 8ccbe22e..aa3ab573 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField.h +++ b/MVMCoreUI/Atoms/TextFields/MFTextField.h @@ -74,6 +74,7 @@ //default error message @property (nullable, strong, nonatomic) NSString *errMessage; +@property (nullable, strong, nonatomic) IBOutlet NSLayoutConstraint *errorHeightConstraint; @property (nullable, copy, nonatomic) void (^editCompleteAction)(NSString * _Nullable text); diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField.m b/MVMCoreUI/Atoms/TextFields/MFTextField.m index cfef9090..fec796bf 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField.m +++ b/MVMCoreUI/Atoms/TextFields/MFTextField.m @@ -558,6 +558,7 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol]; diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField.xib b/MVMCoreUI/Atoms/TextFields/MFTextField.xib index cb9821f1..c11beb5c 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField.xib +++ b/MVMCoreUI/Atoms/TextFields/MFTextField.xib @@ -1,11 +1,9 @@ - - - - + + - + @@ -15,6 +13,7 @@ + diff --git a/MVMCoreUI/Atoms/Views/DropDown.swift b/MVMCoreUI/Atoms/Views/DropDown.swift new file mode 100644 index 00000000..88d0a2c2 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/DropDown.swift @@ -0,0 +1,55 @@ +// +// DropDown.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 11/26/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class DropDown: MFTextField { + let picker = MVMCoreUICommonViewsUtility.commonPickerView()! + + public override func getNib() -> UINib? { + return UINib(nibName: String(describing: MFTextField.self), bundle: MVMCoreUIUtility.bundleForMVMCoreUI()) + } + + public override func setupView() { + super.setupView() + dropDownCarrotWidth?.isActive = false + errorHeightConstraint?.constant = 0 + } + + override public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + guard let textField = textField, textField.inputView == nil else { return } + picker.delegate = self + picker.dataSource = self + picker.tag = textField.tag + textField.inputView = picker + picker.reloadAllComponents() + MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegateObject?.uiTextFieldDelegate) + textField.text = json?.stringWithChainOfKeysOrIndexes([KeyValue,picker.selectedRow(inComponent: 0)]) + } +} + +extension DropDown: UIPickerViewDelegate { + public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + return json?.stringWithChainOfKeysOrIndexes([KeyValue,row]) + } + + public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + textField?.text = json?.stringWithChainOfKeysOrIndexes([KeyValue,row]) + } +} + +extension DropDown: UIPickerViewDataSource { + public func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return json?.optionalArrayForKey(KeyValue)?.count ?? 0 + } +} diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 8474d74a..b2cc4f56 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -212,9 +212,12 @@ public typealias ActionBlock = () -> () } @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { - guard let label = label else { return } - label.attributedText = nil + + // Some properties can only be set on Label. + // Label fonts should not be scaled because it will be scaled in updateView. + let mvmLabel = label as? Label + label.text = json?.optionalStringForKey(KeyText) setLabel(label, withHTML: json?.optionalStringForKey("html")) @@ -230,9 +233,7 @@ public typealias ActionBlock = () -> () } } - if let wholeViewIsClickable = json?.boolForKey("makeWholeViewClickable") { - (label as? Label)?.makeWholeViewClickable = wholeViewIsClickable - } + mvmLabel?.makeWholeViewClickable = json?.boolForKey("makeWholeViewClickable") ?? false if let backgroundColorHex = json?.optionalStringForKey(KeyBackgroundColor), !backgroundColorHex.isEmpty { label.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) @@ -241,12 +242,12 @@ public typealias ActionBlock = () -> () label.accessibilityLabel = json?.optionalStringForKey("accessibilityText") if let fontStyle = json?.optionalStringForKey("fontStyle") { - MFStyler.styleLabel(label, withStyle: fontStyle) + MFStyler.styleLabel(label, withStyle: fontStyle, genericScaling: mvmLabel == nil) } else { let fontSize = json?["fontSize"] as? CGFloat if let fontName = json?.optionalStringForKey("fontName") { - label.font = MFFonts.mfFont(withName: fontName, size: fontSize ?? label.font.pointSize) + label.font = MFFonts.mfFont(withName: fontName, size: fontSize ?? mvmLabel?.standardFontSize ?? label.font.pointSize) } else if let fontSize = fontSize { label.font = label.font.withSize(fontSize) } @@ -256,8 +257,8 @@ public typealias ActionBlock = () -> () label.textColor = UIColor.mfGet(forHex: textColorHex) } - if let attributes = json?.arrayForKey("attributes"), let labelText = label.text { - let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: label.font as UIFont, + if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text { + let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont, NSAttributedString.Key.foregroundColor: label.textColor as UIColor]) for case let attribute as [String: Any] in attributes { guard let attributeType = attribute.optionalStringForKey(KeyType), @@ -298,7 +299,7 @@ public typealias ActionBlock = () -> () case "font": if let fontStyle = attribute.optionalStringForKey("style") { - let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) + let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle, genericScaling: mvmLabel == nil) attributedString.removeAttribute(.font, range: range) attributedString.removeAttribute(.foregroundColor, range: range) attributedString.addAttributes(styles.attributes(at: 0, effectiveRange: nil), range: range) @@ -307,7 +308,7 @@ public typealias ActionBlock = () -> () var font: UIFont? if let fontName = attribute.optionalStringForKey("name") { - font = MFFonts.mfFont(withName: fontName, size: fontSize ?? label.font.pointSize) + font = MFFonts.mfFont(withName: fontName, size: fontSize ?? mvmLabel?.standardFontSize ?? label.font.pointSize) } else if let fontSize = fontSize { font = label.font.withSize(fontSize) } @@ -330,6 +331,7 @@ public typealias ActionBlock = () -> () } } label.attributedText = attributedString + mvmLabel?.originalAttributedString = attributedString } } @@ -419,7 +421,7 @@ public typealias ActionBlock = () -> () if let floatScale = scaleSize?.floatValue { updateView(CGFloat(floatScale)) } else { - updateView(MVMCoreUISplitViewController.getApplicationViewWidth()) + updateView(MVMCoreUIUtility.getWidth()) } } else { standardFontSize = 0 @@ -581,8 +583,6 @@ extension Label { @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { clauses = [] Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData) - originalAttributedString = attributedText - hero = json?["hero"] as? Int } diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index 66a3a83d..f7aaf7f6 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -357,7 +357,6 @@ if (!self.constrainedView) { [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; } - [self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if (self.shouldSetupMoleculeFromJSON) { NSDictionary *moleculeJSON = [json dict:KeyMolecule]; if (self.molecule) { diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift new file mode 100644 index 00000000..518e3b51 --- /dev/null +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -0,0 +1,70 @@ +// +// DropDownFilterTableViewCell.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 9/6/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class DropDownFilterTableViewCell: TableViewCell { + let dropDown = DropDown(forDropDownWithBothDelegates: nil) + var delegateObject: MVMCoreUIDelegateObject? + var previousIndex = NSNotFound + var dropDownSelectionObservation: NSKeyValueObservation? + + // MARK: - MFViewProtocol + override public func setupView() { + super.setupView() + guard let dropDown = dropDown, dropDown.superview == nil else { + return + } + bottomMarginPadding = 0 + + dropDown.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(dropDown) + + NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: dropDown, useMargins: true).values)) + + #warning("Once we have the state manager, we will need to change this logic to only add or remove on user selection...Want to avoid re-use crashes from array size differences") + dropDownSelectionObservation = observe( + \.dropDown?.textField?.text, + options: [.old, .new] + ) { [weak self] object, change in + guard change.newValue != change.oldValue, let self = self, + let options = self.dropDown?.json?.optionalArrayForKey(KeyValue) as? [NSString], + let index = options.firstIndex(of: change.newValue!! as NSString), + let moleculesArrays = self.json?.arrayForKey(KeyMolecules) as? [[[AnyHashable: Any]]] else { return } + + if self.previousIndex != NSNotFound { + let previousMolecules = moleculesArrays[self.previousIndex] + self.delegateObject?.moleculeDelegate?.removeMolecules?(previousMolecules, sender: self, animation: .fade) + } + let molecules = moleculesArrays[index] + self.delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: .fade) + self.previousIndex = index + } + } + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + dropDown?.updateView(size) + } + + // MARK: - MoleculeDelegateProtocol + public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + bottomSeparatorView?.style = .none + self.delegateObject = delegateObject + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + dropDown?.mfTextFieldDelegate = delegateObject?.uiTextFieldDelegate as? MFTextFieldDelegate + dropDown?.uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate + dropDown?.setWithJSON(json?.optionalDictionaryForKey("dropDown"), delegateObject: delegateObject, additionalData: additionalData) + } + + public override func reset() { + super.reset() + bottomMarginPadding = 0 + bottomSeparatorView?.style = .none + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 4303dc55..51a07225 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -35,10 +35,11 @@ @"footer": StandardFooterView.class, @"caretView": CaretView.class, @"caretButton": CaretButton.class, - @"textField" : MFTextField.class, - @"digitTextField" : MFDigitTextField.class, - @"checkbox" : Checkbox.class, - @"checkboxWithLabel" : CheckboxWithLabelView.class, + @"textField": MFTextField.class, + @"dropDown": DropDown.class, + @"digitTextField": MFDigitTextField.class, + @"checkbox": Checkbox.class, + @"checkboxWithLabel": CheckboxWithLabelView.class, @"cornerLabels" : CornerLabels.class, @"progressbar": ProgressBar.class, @"circleProgress": GraphView.class, @@ -63,6 +64,7 @@ @"headlineBodyTextButton": HeadlineBodyTextButton.class, @"headlineBodyTextButtonSwitch": HeadlineBodyTextButtonSwitch.class, @"tabsListItem": TabsTableViewCell.class, + @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class } mutableCopy]; diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index 5b73c8e2..bdef57ba 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -210,6 +210,7 @@ B3 -> Legal /// Will style the label based on the string. Accepted values, H1, H2, H3, H32, B1, B2, B3, B20 + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style; ++ (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label; @@ -258,6 +259,7 @@ B3 -> Legal /// Will style the string based on the string. Accepted values, H1, H2, H3, H32, B1, B2, B3, B20 + (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style; ++ (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; + (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string font:(nonnull UIFont *)font color:(nonnull UIColor *)color; + (nonnull NSAttributedString *)styleGetH1AttributedString:(nullable NSString *)string; @@ -266,6 +268,14 @@ B3 -> Legal + (nonnull NSAttributedString *)styleGetB1AttributedString:(nullable NSString *)string; + (nonnull NSAttributedString *)styleGetB2AttributedString:(nullable NSString *)string; + (nonnull NSAttributedString *)styleGetB3AttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetH1AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetH2AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetH3AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetH32AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetB1AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetB2AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetB3AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; ++ (nonnull NSAttributedString *)styleGetB20AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + (nonnull NSAttributedString *)styleGetDisabledB2AttributedString:(nullable NSString *)string; + (nonnull NSAttributedString *)styleGetDisabledB1AttributedString:(nullable NSString *)string; diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index 18246f7f..c3dc8946 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -516,26 +516,30 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; #pragma mark - 2.0 Styles -+ (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style { ++ (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { if ([style isEqualToString:@"H1"]) { - [self styleLabelH1:label]; + [self styleLabelH1:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"H2"]) { - [self styleLabelH2:label]; + [self styleLabelH2:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"H3"]) { - [self styleLabelH3:label]; + [self styleLabelH3:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"H32"]) { - [self styleLabelH32:label]; + [self styleLabelH32:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"B1"]) { - [self styleLabelB1:label]; + [self styleLabelB1:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"B3"]) { - [self styleLabelB3:label]; + [self styleLabelB3:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"B20"]) { - [self styleLabelB20:label]; + [self styleLabelB20:label genericScaling:genericScaling]; } else { - [self styleLabelB2:label]; + [self styleLabelB2:label genericScaling:genericScaling]; } } ++ (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style { + [self styleLabel:label withStyle:style genericScaling:YES]; +} + + (void)styleLabelH1:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { label.font = [MFStyler fontH1:genericScaling]; label.textColor = [UIColor blackColor]; @@ -656,22 +660,26 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; #pragma mark - Attributed Strings + (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style { + return [self styleGetAttributedString:string withStyle:style genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { if ([style isEqualToString:@"H1"]) { - return [self styleGetH1AttributedString:string]; + return [self styleGetH1AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"H2"]) { - return [self styleGetH2AttributedString:string]; + return [self styleGetH2AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"H3"]) { - return [self styleGetH3AttributedString:string]; + return [self styleGetH3AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"H32"]) { - return [self styleGetH32AttributedString:string]; + return [self styleGetH32AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"B1"]) { - return [self styleGetB1AttributedString:string]; + return [self styleGetB1AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"B3"]) { - return [self styleGetB3AttributedString:string]; + return [self styleGetB3AttributedString:string genericScaling:genericScaling]; } else if ([style isEqualToString:@"B20"]) { - return [self styleGetB20AttributedString:string]; + return [self styleGetB20AttributedString:string genericScaling:genericScaling]; } else { - return [self styleGetB2AttributedString:string]; + return [self styleGetB2AttributedString:string genericScaling:genericScaling]; } } @@ -690,35 +698,67 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; } + (nonnull NSAttributedString *)styleGetH1AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontH1] color:[UIColor blackColor]]; + return [MFStyler styleGetH1AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetH1AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontH1:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetH2AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontH2] color:[UIColor blackColor]]; + return [MFStyler styleGetH2AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetH2AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontH2:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetH3AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontH3] color:[UIColor blackColor]]; + return [MFStyler styleGetH3AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetH3AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontH3:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetH32AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontH32] color:[UIColor blackColor]]; + return [MFStyler styleGetH32AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetH32AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontH32:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetB1AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontB1] color:[UIColor blackColor]]; + return [MFStyler styleGetB1AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetB1AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontB1:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetB2AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontB2] color:[UIColor blackColor]]; + return [MFStyler styleGetB2AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetB2AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontB2:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetB3AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontB3] color:[UIColor mfBattleshipGrey]]; + return [MFStyler styleGetB3AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetB3AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontB3:genericScaling] color:[UIColor mfBattleshipGrey]]; } + (nonnull NSAttributedString *)styleGetB20AttributedString:(nullable NSString *)string { - return [MFStyler styleGetAttributedString:string font:[MFStyler fontB20] color:[UIColor blackColor]]; + return [MFStyler styleGetB20AttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetB20AttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontB20:genericScaling] color:[UIColor blackColor]]; } + (nonnull NSAttributedString *)styleGetDisabledB1AttributedString:(nullable NSString *)string { From f5270ae12e38ae7ed0874d532e8088ebc9d67032 Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Wed, 27 Nov 2019 14:03:51 -0500 Subject: [PATCH 03/59] remove navigation bar check for manual inset calculation as it impacts presented controllers --- MVMCoreUI/BaseControllers/MFScrollingViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/MFScrollingViewController.m b/MVMCoreUI/BaseControllers/MFScrollingViewController.m index 56019cb7..67e01d93 100644 --- a/MVMCoreUI/BaseControllers/MFScrollingViewController.m +++ b/MVMCoreUI/BaseControllers/MFScrollingViewController.m @@ -91,7 +91,7 @@ static NSTimeInterval const HandScrollAnimationTiming = 7.f; - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; - BOOL automaticInset = self.navigationController && self.scrollView.contentInsetAdjustmentBehavior == UIScrollViewContentInsetAdjustmentAutomatic; + BOOL automaticInset = self.scrollView.contentInsetAdjustmentBehavior == UIScrollViewContentInsetAdjustmentAutomatic; // Takes into account the navigation bar. if (!automaticInset && (self.edgesForExtendedLayout & UIRectEdgeTop)) { From ee773eed89ac2e3e71cd743f6497e24deb65591b Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 27 Nov 2019 15:02:03 -0500 Subject: [PATCH 04/59] key change --- MVMCoreUI/Atoms/Views/DropDown.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/DropDown.swift b/MVMCoreUI/Atoms/Views/DropDown.swift index 88d0a2c2..929bd67f 100644 --- a/MVMCoreUI/Atoms/Views/DropDown.swift +++ b/MVMCoreUI/Atoms/Views/DropDown.swift @@ -30,17 +30,17 @@ import UIKit textField.inputView = picker picker.reloadAllComponents() MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegateObject?.uiTextFieldDelegate) - textField.text = json?.stringWithChainOfKeysOrIndexes([KeyValue,picker.selectedRow(inComponent: 0)]) + textField.text = json?.stringWithChainOfKeysOrIndexes(["options",picker.selectedRow(inComponent: 0)]) } } extension DropDown: UIPickerViewDelegate { public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - return json?.stringWithChainOfKeysOrIndexes([KeyValue,row]) + return json?.stringWithChainOfKeysOrIndexes(["options",row]) } public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - textField?.text = json?.stringWithChainOfKeysOrIndexes([KeyValue,row]) + textField?.text = json?.stringWithChainOfKeysOrIndexes(["options",row]) } } @@ -50,6 +50,6 @@ extension DropDown: UIPickerViewDataSource { } public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return json?.optionalArrayForKey(KeyValue)?.count ?? 0 + return json?.optionalArrayForKey("options")?.count ?? 0 } } From dc5174cbe4e38f97addeeea00663e9ca1d541235 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Thu, 28 Nov 2019 20:48:07 +0530 Subject: [PATCH 05/59] key name mismatch fix. --- MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 518e3b51..31a6cc61 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -33,7 +33,7 @@ import UIKit options: [.old, .new] ) { [weak self] object, change in guard change.newValue != change.oldValue, let self = self, - let options = self.dropDown?.json?.optionalArrayForKey(KeyValue) as? [NSString], + let options = self.dropDown?.json?.optionalArrayForKey("options") as? [NSString], let index = options.firstIndex(of: change.newValue!! as NSString), let moleculesArrays = self.json?.arrayForKey(KeyMolecules) as? [[[AnyHashable: Any]]] else { return } From 3e46438fd0be5c32707fadee2d201b9a68c59a68 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 2 Dec 2019 10:11:04 -0500 Subject: [PATCH 06/59] label font bugfix caused by the dissonance between label and styler setting.... --- MVMCoreUI/Atoms/Views/Label.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index b2cc4f56..99a28463 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -243,8 +243,12 @@ public typealias ActionBlock = () -> () if let fontStyle = json?.optionalStringForKey("fontStyle") { MFStyler.styleLabel(label, withStyle: fontStyle, genericScaling: mvmLabel == nil) + mvmLabel?.standardFontSize = label.font.pointSize } else { let fontSize = json?["fontSize"] as? CGFloat + if let fontSize = fontSize { + mvmLabel?.standardFontSize = fontSize + } if let fontName = json?.optionalStringForKey("fontName") { label.font = MFFonts.mfFont(withName: fontName, size: fontSize ?? mvmLabel?.standardFontSize ?? label.font.pointSize) From b443c4a3897c0031019af5dfd5d9a76d5b2f1f0a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 2 Dec 2019 17:33:06 -0500 Subject: [PATCH 07/59] 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 08/59] 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 3f9b707d37e71da6da8dc1a232700699b30c1a30 Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Wed, 4 Dec 2019 12:56:38 -0500 Subject: [PATCH 09/59] Add overtaking indicator to openPanel callback method. --- .../MVMCoreUIDetailViewProtocol.h | 2 ++ .../MVMCoreUISplitViewController.m | 30 ++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIDetailViewProtocol.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIDetailViewProtocol.h index 038769fb..377508c7 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUIDetailViewProtocol.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUIDetailViewProtocol.h @@ -16,7 +16,9 @@ NS_ASSUME_NONNULL_BEGIN @optional - (void)panelWillAppear:(nonnull NSObject *)panel; +- (void)panelWillAppear:(nonnull NSObject *)panel overtakingDetail:(BOOL)willOvertake; - (void)panelDidAppear:(nonnull NSObject *)panel; +- (void)panelDidAppear:(nonnull NSObject *)panel overtakingDetail:(BOOL)didOvertake; - (void)panelWillDisappear:(nonnull NSObject *)panel; - (void)panelDidDisappear:(nonnull NSObject *)panel; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index b529ac19..b5177b9b 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -357,16 +357,19 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)showLeftPanelAnimated:(BOOL)animated explict:(BOOL)explict { [MVMCoreDispatchUtility performBlockOnMainThread:^{ if (self.mainViewLeading.constant < .1) { + BOOL shouldExtendLeftPanel = [self shouldExtendLeftPanel]; + if (explict) { self.explictlyShowingPanel = self.leftPanel; } + void (^animations)(void) = [self getLeftPanelShowAnimationBlock]; void (^completion)(BOOL) = ^(BOOL finished){ - [self panelDidAppear:self.leftPanel animated:animated]; + [self panelDidAppear:self.leftPanel didExtend:shouldExtendLeftPanel animated:animated]; }; - if (![self shouldExtendLeftPanel]) { + if (!shouldExtendLeftPanel) { if ([self.leftPanel respondsToSelector:@selector(showArrow)]){ [self.leftPanel showArrow]; } @@ -389,7 +392,7 @@ CGFloat const PanelAnimationDuration = 0.2; } self.mainViewCoverView.hidden = NO; - [self panelWillAppear:self.leftPanel animated:animated]; + [self panelWillAppear:self.leftPanel willExtend:shouldExtendLeftPanel animated:animated]; if (animated) { [UIView animateWithDuration:PanelAnimationDuration delay:0 options:UIViewAnimationOptionCurveLinear animations:animations completion:completion]; } else { @@ -547,19 +550,22 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)showRightPanelAnimated:(BOOL)animated explict:(BOOL)explict { [MVMCoreDispatchUtility performBlockOnMainThread:^{ if (self.mainViewTrailing.constant < .1) { + BOOL shouldExtendRightPanel = [self shouldExtendRightPanel]; + if (explict) { self.explictlyShowingPanel = self.rightPanel; } + void (^animations)(void) = [self getRightPanelShowAnimationBlock]; void (^completion)(BOOL) = ^(BOOL finished){ - [self panelDidAppear:self.rightPanel animated:animated]; + [self panelDidAppear:self.rightPanel didExtend:shouldExtendRightPanel animated:animated]; self.mainView.accessibilityElementsHidden = YES; UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.rightPanel); }; self.mainViewCoverView.hidden = NO; - if (![self shouldExtendRightPanel]) { + if (!shouldExtendRightPanel) { if ([self.rightPanel respondsToSelector:@selector(showArrow)]){ [self.rightPanel showArrow]; } @@ -579,7 +585,7 @@ CGFloat const PanelAnimationDuration = 0.2; self.rightPanelSeparator = rightPanelSeparator; } - [self panelWillAppear:self.rightPanel animated:animated]; + [self panelWillAppear:self.rightPanel willExtend:shouldExtendRightPanel animated:animated]; if (animated) { [UIView animateWithDuration:PanelAnimationDuration delay:0 options:UIViewAnimationOptionCurveLinear animations:animations completion:completion]; } else { @@ -612,7 +618,7 @@ CGFloat const PanelAnimationDuration = 0.2; [self hideRightPanelIfNeededAnimated:YES]; } -- (void)panelWillAppear:(UIViewController *)panel animated:(BOOL)animated { +- (void)panelWillAppear:(UIViewController *)panel willExtend:(BOOL)willExtend animated:(BOOL)animated { if ([panel respondsToSelector:@selector(willAppear:)]) { [panel willAppear:animated]; } else { @@ -621,13 +627,15 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = [self getCurrentDetailViewController]; if ([controller.class conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)]) { UIViewController * protocolController = (UIViewController *)controller; - if ([protocolController respondsToSelector:@selector(panelWillAppear:)]) { + if ([protocolController respondsToSelector:@selector(panelWillAppear:overtakingDetail:)]) { + [protocolController panelWillAppear:panel overtakingDetail:!willExtend]; + } else if ([protocolController respondsToSelector:@selector(panelWillAppear:)]) { [protocolController panelWillAppear:panel]; } } } -- (void)panelDidAppear:(UIViewController *)panel animated:(BOOL)animated { +- (void)panelDidAppear:(UIViewController *)panel didExtend:(BOOL)didExtend animated:(BOOL)animated { if ([panel respondsToSelector:@selector(didAppear:)]) { [panel didAppear:animated]; } else { @@ -636,7 +644,9 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = [self getCurrentDetailViewController]; if ([controller.class conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)]) { UIViewController * protocolController = (UIViewController *)controller; - if ([protocolController respondsToSelector:@selector(panelDidAppear:)]) { + if ([protocolController respondsToSelector:@selector(panelDidAppear:overtakingDetail:)]) { + [protocolController panelDidAppear:panel overtakingDetail:!didExtend]; + } else if ([protocolController respondsToSelector:@selector(panelDidAppear:)]) { [protocolController panelDidAppear:panel]; } } From d95e42330eaf9bce9aacd0597983b6a84f5c9270 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 4 Dec 2019 13:09:50 -0500 Subject: [PATCH 10/59] moving files --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++++++------ MVMCoreUI/{Atoms => Legacy}/Views/MFRadioButton.h | 0 MVMCoreUI/{Atoms => Legacy}/Views/MFRadioButton.m | 0 .../{Atoms => Legacy}/Views/MVMCoreUICheckBox.h | 0 .../{Atoms => Legacy}/Views/MVMCoreUICheckBox.m | 0 .../{Atoms => Legacy}/Views/MVMCoreUICheckMarkView.h | 0 .../{Atoms => Legacy}/Views/MVMCoreUICheckMarkView.m | 0 .../Items/DropDownFilterTableViewCell.swift | 2 +- MVMCoreUI/Organisms/MoleculeStackView.swift | 4 ++-- 9 files changed, 9 insertions(+), 9 deletions(-) rename MVMCoreUI/{Atoms => Legacy}/Views/MFRadioButton.h (100%) rename MVMCoreUI/{Atoms => Legacy}/Views/MFRadioButton.m (100%) rename MVMCoreUI/{Atoms => Legacy}/Views/MVMCoreUICheckBox.h (100%) rename MVMCoreUI/{Atoms => Legacy}/Views/MVMCoreUICheckBox.m (100%) rename MVMCoreUI/{Atoms => Legacy}/Views/MVMCoreUICheckMarkView.h (100%) rename MVMCoreUI/{Atoms => Legacy}/Views/MVMCoreUICheckMarkView.m (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 515e24ee..900edec2 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -454,6 +454,12 @@ D29DF31F21ED0CBA003B2FB9 /* LabelView.m */, D29DF15921E697DA003B2FB9 /* SeparatorView.h */, D29DF15A21E697DA003B2FB9 /* SeparatorView.m */, + D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */, + D22D1F1D220343560077CEC0 /* MVMCoreUICheckMarkView.m */, + D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */, + D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */, + 0198F7A02256A80A0066C936 /* MFRadioButton.h */, + 0198F7A22256A80A0066C936 /* MFRadioButton.m */, ); path = Views; sourceTree = ""; @@ -764,16 +770,10 @@ D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */, D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */, D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */, - D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */, - D22D1F1D220343560077CEC0 /* MVMCoreUICheckMarkView.m */, - D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */, - D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */, D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */, D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, DB891E822253FA8500022516 /* Label.swift */, - 0198F7A02256A80A0066C936 /* MFRadioButton.h */, - 0198F7A22256A80A0066C936 /* MFRadioButton.m */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, diff --git a/MVMCoreUI/Atoms/Views/MFRadioButton.h b/MVMCoreUI/Legacy/Views/MFRadioButton.h similarity index 100% rename from MVMCoreUI/Atoms/Views/MFRadioButton.h rename to MVMCoreUI/Legacy/Views/MFRadioButton.h diff --git a/MVMCoreUI/Atoms/Views/MFRadioButton.m b/MVMCoreUI/Legacy/Views/MFRadioButton.m similarity index 100% rename from MVMCoreUI/Atoms/Views/MFRadioButton.m rename to MVMCoreUI/Legacy/Views/MFRadioButton.m diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.h b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.h similarity index 100% rename from MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.h rename to MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.h diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m similarity index 100% rename from MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.m rename to MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.h b/MVMCoreUI/Legacy/Views/MVMCoreUICheckMarkView.h similarity index 100% rename from MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.h rename to MVMCoreUI/Legacy/Views/MVMCoreUICheckMarkView.h diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckMarkView.m similarity index 100% rename from MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.m rename to MVMCoreUI/Legacy/Views/MVMCoreUICheckMarkView.m diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 518e3b51..31a6cc61 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -33,7 +33,7 @@ import UIKit options: [.old, .new] ) { [weak self] object, change in guard change.newValue != change.oldValue, let self = self, - let options = self.dropDown?.json?.optionalArrayForKey(KeyValue) as? [NSString], + let options = self.dropDown?.json?.optionalArrayForKey("options") as? [NSString], let index = options.firstIndex(of: change.newValue!! as NSString), let moleculesArrays = self.json?.arrayForKey(KeyMolecules) as? [[[AnyHashable: Any]]] else { return } diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index cafe21b0..dc7cc81e 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -264,7 +264,7 @@ public class MoleculeStackView: ViewConstrainingView { } else if let previousView = items.last(where: { stackItem in return !stackItem.gone })?.view { - _ = NSLayoutConstraint(pinFirstView: previousView, toSecondView: view, withConstant: spacing, directionVertical: true) + view.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0) @@ -281,7 +281,7 @@ public class MoleculeStackView: ViewConstrainingView { } else if let previousView = items.last(where: { stackItem in return !stackItem.gone })?.view { - _ = NSLayoutConstraint(pinFirstView: previousView, toSecondView: view, withConstant: spacing, directionVertical: false) + view.leftAnchor.constraint(equalTo: previousView.rightAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) From aaa8e4132ebb454db8a3cd8244a7ea8d64128bf0 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 4 Dec 2019 16:25:31 -0500 Subject: [PATCH 11/59] 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 12/59] 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 13/59] 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 14/59] 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 15/59] 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 16/59] 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 17/59] 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 18/59] 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 19/59] 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 20/59] 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 21/59] 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 22/59] 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 23/59] 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 24/59] 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 25/59] 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 26/59] 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 27/59] 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 28/59] 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 29/59] 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 30/59] 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 31/59] 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 32/59] 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 33/59] 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]?) { From fbc6e83038118ed29faa51a67ef52875e6a607e7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 20 Dec 2019 13:27:22 -0500 Subject: [PATCH 34/59] Created Protocol to centralize tap detection logic. --- MVMCoreUI.xcodeproj/project.pbxproj | 12 +++++++ MVMCoreUI/BaseClasses/Control.swift | 16 ++++------ .../Protocols/AppleGuidelinesProtocol.swift | 32 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c26f4c..2150daf1 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; + 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; @@ -226,6 +227,7 @@ 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; + 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = ""; }; 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = ""; }; @@ -438,6 +440,14 @@ path = FormUIHelpers; sourceTree = ""; }; + 0A5D59C323AD488600EFD9E9 /* Protocols */ = { + isa = PBXGroup; + children = ( + 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */, + ); + path = Protocols; + sourceTree = ""; + }; D213347423842FE3008E41B3 /* Controllers */ = { isa = PBXGroup; children = ( @@ -910,6 +920,7 @@ children = ( D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, + 0A5D59C323AD488600EFD9E9 /* Protocols */, ); path = BaseClasses; sourceTree = ""; @@ -1072,6 +1083,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */, D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index 5774ff5a..0b03ba27 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -47,18 +47,14 @@ import UIKit setupView() } } - - //-------------------------------------------------- - // MARK: - UITouch - //-------------------------------------------------- - +} + +// MARK: - AppleGuidelinesProtocol +extension Control: AppleGuidelinesProtocol { + override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - // If the control is smaller than 44pt by width or height, this will compensate. - let faultToleranceX: CGFloat = max((MinimumTappableArea - bounds.size.width) / 2.0, 0) - let faultToleranceY: CGFloat = max((MinimumTappableArea - bounds.size.height) / 2.0, 0) - let area = bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY) - return area.contains(point) + return Self.acceptablyOutsideBounds(point: point, bounds: bounds) } } diff --git a/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift b/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift new file mode 100644 index 00000000..3498a274 --- /dev/null +++ b/MVMCoreUI/BaseClasses/Protocols/AppleGuidelinesProtocol.swift @@ -0,0 +1,32 @@ +// +// AppleGuidelinesProtocol.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 12/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + + +public protocol AppleGuidelinesProtocol { + static var minimumTappableArea: CGFloat { get } + static func acceptablyOutsideBounds(point: CGPoint, bounds: CGRect) -> Bool +} + +extension AppleGuidelinesProtocol { + + static public var minimumTappableArea: CGFloat { + return 44.0 + } + + // If the control is smaller than 44pt by width or height, this will compensate. + static public func acceptablyOutsideBounds(point: CGPoint, bounds: CGRect) -> Bool { + + let faultToleranceX: CGFloat = max((minimumTappableArea - bounds.size.width) / 2.0, 0) + let faultToleranceY: CGFloat = max((minimumTappableArea - bounds.size.height) / 2.0, 0) + let area = bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY) + + return area.contains(point) + } +} From 1d843ae29a6c2eafcaf5227ef4f97d2e3009fbb9 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Thu, 26 Dec 2019 19:33:37 +0530 Subject: [PATCH 35/59] main thread update access modifier update --- MVMCoreUI/Molecules/MFTextFieldListView.swift | 24 ++++++++++++++----- .../TextFieldListFormViewController.swift | 14 +++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift index 6d24e19a..6655cf01 100644 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ b/MVMCoreUI/Molecules/MFTextFieldListView.swift @@ -46,7 +46,7 @@ public class MFTextFieldListView: ViewConstrainingView { var viewList: [UIView] = [] for textFieldMap in textFieldMapList { - if let textField = MFTextField(map: textFieldMap, bothDelegates: self) { + if let textField = getTextFieldForMap(textFieldMap) { if textFieldMap.boolForKey("required") { textFieldsToValidate.append(textField) @@ -76,13 +76,25 @@ public class MFTextFieldListView: ViewConstrainingView { } public func getTextParamsList() -> [String: Any] { - var extraParam: [String: Any] = [:] - for textField in textFields { - if let fieldKey = textField.fieldKey { - extraParam[fieldKey as String] = textField.text ?? "" + return DispatchQueue.main.sync { + var extraParam: [String: Any] = [:] + for textField in textFields { + if let fieldKey = textField.fieldKey { + extraParam[fieldKey as String] = textField.text ?? "" + } } + return extraParam } - return extraParam + } + + private func getTextFieldForMap(_ map: [String: Any]) -> MFTextField? { + if map.boolForKey("dropDown") { + let dropDownFld = DropDown(map: map, bothDelegates: self) + dropDownFld?.setWithJSON(map, delegateObject: parentViewContoller?.delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) + dropDownFld?.showDropDown(true) + return dropDownFld + } + return MFTextField(map: map, bothDelegates: self) } } diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift index bf3b0bea..6aa3eec7 100644 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ b/MVMCoreUI/Templates/TextFieldListFormViewController.swift @@ -8,26 +8,26 @@ import UIKit -public class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { +open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { public var textFieldListView: MFTextFieldListView? - public override func viewDidLoad() { + open override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } - public override func updateViews() { + open override func updateViews() { super.updateViews() } - public override func newDataBuildScreen() { + open override func newDataBuildScreen() { super.newDataBuildScreen() topLabelsView?.separatorView?.isHidden = true } - public override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { + open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { var viewList: [UIView] = [] if let textFieldsList = loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] { @@ -40,12 +40,12 @@ public class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewContr return viewList } - public override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { + open override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { textFieldListView?.addParams(requestParameters: requestParameters) super.handleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData) } - public override func spaceAboveBetweenView() -> NSNumber? { + open override func spaceAboveBetweenView() -> NSNumber? { return PaddingFour as NSNumber } From ccc535360c2a690ff48012f2bed7c3252b25f2d3 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 27 Dec 2019 13:02:13 +0530 Subject: [PATCH 36/59] protocol implementation --- MVMCoreUI/Molecules/MFTextFieldListView.swift | 8 ++++++++ .../TextFieldListFormViewController.swift | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift index 6655cf01..c695c3a3 100644 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ b/MVMCoreUI/Molecules/MFTextFieldListView.swift @@ -9,6 +9,10 @@ import UIKit import MVMCore +@objc public protocol TextFieldListHelperProtocol { + @objc optional func fieldForMap(_ map: [String: Any], textField: MFTextField) + @objc optional func spaceBetweenField() -> CGFloat +} public class MFTextFieldListView: ViewConstrainingView { @@ -48,6 +52,8 @@ public class MFTextFieldListView: ViewConstrainingView { for textFieldMap in textFieldMapList { if let textField = getTextFieldForMap(textFieldMap) { + (parentViewContoller as? TextFieldListHelperProtocol)?.fieldForMap?(textFieldMap, textField: textField) + if textFieldMap.boolForKey("required") { textFieldsToValidate.append(textField) } @@ -60,11 +66,13 @@ public class MFTextFieldListView: ViewConstrainingView { } } + let spaceBtwField = (parentViewContoller as? TextFieldListHelperProtocol)?.spaceBetweenField?() ?? 0.0 StackableViewController.populateView(self, withUIArray: viewList) { (viewObject) -> UIEdgeInsets in var edgeInsets = StackableViewController.standardSpaceAroundUIObject() edgeInsets.left = 0 edgeInsets.right = 0 edgeInsets.top = 0 + edgeInsets.bottom = spaceBtwField return edgeInsets } diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift index 6aa3eec7..c0509679 100644 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ b/MVMCoreUI/Templates/TextFieldListFormViewController.swift @@ -8,7 +8,7 @@ import UIKit -open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController { +open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController, TextFieldListHelperProtocol { public var textFieldListView: MFTextFieldListView? @@ -30,7 +30,7 @@ open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewControl open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { var viewList: [UIView] = [] - if let textFieldsList = loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] { + if let textFieldsList = textFieldsLists() { let textFieldListView = MFTextFieldListView(textFieldMapList: textFieldsList, parentViewContoller: self, primaryButton: self.primaryButton) @@ -48,5 +48,18 @@ open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewControl open override func spaceAboveBetweenView() -> NSNumber? { return PaddingFour as NSNumber } + + open func textFieldsLists() -> [[String: Any]]? { + return loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] + } + + //MARK: - Textfield list protocol + open func spaceBetweenField() -> CGFloat { + return 0.0 + } + + open func fieldForMap(_ map: [String : Any], textField: MFTextField) { + + } } From e5ca7b5c9e2996091496750180a871843d3cbf97 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Thu, 2 Jan 2020 21:33:31 +0530 Subject: [PATCH 37/59] bullet list molecule added --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Molecules/BulletList.swift | 233 ++++++++++++++++++ .../MVMCoreUIMoleculeMappingObject.m | 3 +- 3 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Molecules/BulletList.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c26f4c..14506f07 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63D632023BDC3A0008F3B1F /* BulletList.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -233,6 +234,7 @@ 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + C63D632023BDC3A0008F3B1F /* BulletList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulletList.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -633,6 +635,7 @@ 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, + C63D632023BDC3A0008F3B1F /* BulletList.swift */, ); path = Molecules; sourceTree = ""; @@ -1177,6 +1180,7 @@ 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, + C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift new file mode 100644 index 00000000..f680b36a --- /dev/null +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -0,0 +1,233 @@ +// +// BulletList.swift +// MVMCoreUI +// +// Created by Murugan, Vimal on 02/01/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class BulletList: Container { + + var contentView = MVMCoreUICommonViewsUtility.commonView() + var reusableViews: [LeftRightLabelView] = [] + var bulletChar: String? + + /// Restacks the existing items. + func restack() { + //setWithStackItems(items) + } + + /// Removes all stack items views from the view. + func removeAllItemInViews() { + reusableViews.forEach({ $0.removeFromSuperview() }) + } + + /// The spacing to use between each item in the stack. + var verticalSpacing: CGFloat = 8 { + didSet { + if verticalSpacing != oldValue { + restack() + } + } + } + + // MARK: - Inits + public override init() { + super.init() + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.init(frame: CGRect.zero) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Helpers + public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { + let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) + constraint.priority = priority + constraint.isActive = true + } + + // MARK: - MFViewProtocol + public override func setupView() { + super.setupView() + guard contentView.superview == nil else { + return + } + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) + translatesAutoresizingMaskIntoConstraints = false + backgroundColor = .clear + addSubview(contentView) + containerHelper.constrainView(contentView) + contentView.setContentHuggingPriority(.defaultHigh, for: .vertical) + contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal) + } + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + directionalLayoutMargins.leading = 0 + directionalLayoutMargins.trailing = 0 + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + public override func reset() { + super.reset() + backgroundColor = .clear + } + + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + // let previousJSON = self.json + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + removeAllItemInViews() + guard let list = json?.arrayForKey("list") as? [[String: Any]] else { + return + } + + bulletChar = json?.optionalStringForKey("bulletChar") + + var views = [LeftLabelRightContainer]() + // Adds the molecules and sets the json. + for (index, map) in list.enumerated() { + let view = LeftLabelRightContainer() + let moleculeMap = ["left": leftItem(bulletChar ?? String(index + 1)), "right": map] + view.setWithJSON(moleculeMap, delegateObject: delegateObject, additionalData: additionalData) + views.append(view) + } + let lastObj = views.last + MVMCoreUIStackableViewController.populateView(contentView, withUIArray: views) { (obj) -> UIEdgeInsets in + return UIEdgeInsets(top: 0, left: 0, bottom: lastObj?.isEqual(obj) ?? false ? 0 : 16, right: 0) + } + } + + public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { + // This will aggregate names of molecules to make an id. + guard let molecules = molecule?.optionalArrayForKey("list") else { + return "stack<>" + } + var name = "stack<" + for case let item as [AnyHashable: Any] in molecules { + if let molecule = item.optionalDictionaryForKey(KeyMolecule), let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) { + name.append(moleculeName + ",") + } + } + name.append(">") + return name + } + + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + guard let items = json?.optionalArrayForKey("list") else { + return nil + } + var modules: [String] = [] + for case let item as [AnyHashable: AnyHashable] in items { + if let molecule = item.optionalDictionaryForKey(KeyMolecule), let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.requiredModules?(molecule, delegateObject: delegateObject, error: error) { + modules += modulesForMolecule + } + } + return modules.count > 0 ? modules : nil + } + + func leftItem(_ string: String) -> [String: Any] { + return ["moleculeName":"label","text":string, "fontStyle":"B2"] + } + +} + +class LeftLabelRightContainer: View { + + var label = Label.commonLabelB2(true) + var rightContainer = MVMCoreUICommonViewsUtility.commonView() + var leftContainer = MVMCoreUICommonViewsUtility.commonView() + var rightMoleculeName: String? + var rightMolecule: View? + let containerHelper = ContainerHelper() + + var constraintBtwViews: NSLayoutConstraint? + var spaceBtwViews: CGFloat = 8 { + didSet { + if spaceBtwViews != oldValue { + constraintBtwViews?.constant = spaceBtwViews + layoutIfNeeded() + } + } + } + + override func setupView() { + super.setupView() + + guard rightContainer.superview == nil else { + return + } + + translatesAutoresizingMaskIntoConstraints = false + addSubview(rightContainer) + addSubview(leftContainer) + leftContainer.addSubview(label) + NSLayoutConstraint.constraintPinSubview(toSuperview: label) + + NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) + bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true + + NSLayoutConstraint.constraintPinSubview(rightContainer, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) + constraintBtwViews = rightContainer.leftAnchor.constraint(equalTo: leftContainer.rightAnchor, constant: spaceBtwViews) + constraintBtwViews?.priority = .required + constraintBtwViews?.isActive = true + + //TODO: Need to get confirmation on this + leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true + setContentHuggingPriority(.defaultHigh, for: .vertical) + setContentHuggingPriority(.defaultHigh, for: .horizontal) + rightContainer.setContentHuggingPriority(.defaultHigh, for: .vertical) + rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) + + label.setContentHuggingPriority(.defaultHigh, for: .horizontal) + label.setContentHuggingPriority(.defaultHigh, for: .vertical) + + } + + override func updateView(_ size: CGFloat) { + super.updateView(size) + } + + override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + let previousMoleculeName = rightMoleculeName + guard let moleculeJSON = json?.optionalDictionaryForKey("right") else { + removeSubviewsInRightContainer() + return + } + + Label.setUILabel(label, withJSON: json?.optionalDictionaryForKey("left"), delegate: delegateObject, additionalData: additionalData) + rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) + //For reuse purpose check that allready added molecule is same + if rightMolecule != nil && previousMoleculeName == rightMoleculeName { + rightMolecule?.setWithJSON(json?.optionalDictionaryForKey("right"), delegateObject: delegateObject, additionalData: additionalData) + } else { + removeSubviewsInRightContainer() + if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { + addView(molecule) + } + } + } + + func removeSubviewsInRightContainer() { + rightContainer.subviews.forEach({ $0.removeFromSuperview() }) + } + + func addView(_ view: UIView) { + view.translatesAutoresizingMaskIntoConstraints = false + rightContainer.addSubview(view) + containerHelper.constrainView(view) + rightMolecule = view as? View + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 9db7822d..47bbac98 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -66,7 +66,8 @@ @"tabsListItem": TabsTableViewCell.class, @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, - @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class + @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class, + @"bulletList": BulletList.class } mutableCopy]; }); return mapping; From c4fbf578907a066d7d50f4460248f933d4fdc256 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 3 Jan 2020 19:52:10 +0530 Subject: [PATCH 38/59] MOBFIRST-19249 : List Item Style Updates Adding shortDivider and tallDivider style. Removing header style. --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index 9cf77ae1..f1fb3519 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -47,8 +47,10 @@ import UIKit switch styleString { case "standard": styleStandard() - case "header": - styleHeader() + case "shortDivider": + styleShortDivider() + case "tallDivider": + styleTallDivider() case "sectionFooter": styleFooter() case "none": @@ -64,11 +66,18 @@ import UIKit bottomSeparatorView?.style = .standard } - open func styleHeader() { + open func styleTallDivider() { topMarginPadding = 48 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .thin + bottomSeparatorView?.style = .standard + } + + open func styleShortDivider() { + topMarginPadding = 32 + bottomMarginPadding = 16 + topSeparatorView?.style = .none + bottomSeparatorView?.style = .standard } open func styleFooter() { From dd49c439462e02321657788a566efca17190a792 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 3 Jan 2020 20:18:30 +0530 Subject: [PATCH 39/59] code cleanup --- MVMCoreUI/Molecules/BulletList.swift | 137 ++++++++++++++++++--------- 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift index f680b36a..5cb0dbd4 100644 --- a/MVMCoreUI/Molecules/BulletList.swift +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -11,28 +11,14 @@ import UIKit open class BulletList: Container { var contentView = MVMCoreUICommonViewsUtility.commonView() - var reusableViews: [LeftRightLabelView] = [] + var reusableViews: [LeftLabelRightMoleculeContainer] = [] var bulletChar: String? - /// Restacks the existing items. - func restack() { - //setWithStackItems(items) - } - /// Removes all stack items views from the view. func removeAllItemInViews() { reusableViews.forEach({ $0.removeFromSuperview() }) } - /// The spacing to use between each item in the stack. - var verticalSpacing: CGFloat = 8 { - didSet { - if verticalSpacing != oldValue { - restack() - } - } - } - // MARK: - Inits public override init() { super.init() @@ -77,46 +63,72 @@ open class BulletList: Container { super.updateView(size) directionalLayoutMargins.leading = 0 directionalLayoutMargins.trailing = 0 + reusableViews.forEach({ $0.updateView(size) }) } // MARK: - MVMCoreUIMoleculeViewProtocol public override func reset() { super.reset() backgroundColor = .clear + reusableViews.forEach({ $0.reset() }) } open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - // let previousJSON = self.json + let previousJSON = self.json super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) removeAllItemInViews() + // If the items in the stack are the same, just update previous items instead of re-allocating. + var items: [LeftLabelRightMoleculeContainer]? + if BulletList.name(forReuse: previousJSON, delegateObject: delegateObject) == BulletList.name(forReuse: json, delegateObject: delegateObject) { + items = self.reusableViews + } + self.reusableViews = [] + guard let list = json?.arrayForKey("list") as? [[String: Any]] else { return } bulletChar = json?.optionalStringForKey("bulletChar") - - var views = [LeftLabelRightContainer]() // Adds the molecules and sets the json. for (index, map) in list.enumerated() { - let view = LeftLabelRightContainer() - let moleculeMap = ["left": leftItem(bulletChar ?? String(index + 1)), "right": map] - view.setWithJSON(moleculeMap, delegateObject: delegateObject, additionalData: additionalData) - views.append(view) + if let item = items?[index] { + item.leftText = bulletChar + item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) + addView(item, lastItem: index == list.count - 1) + } else { + let leftLabel = LeftLabelRightMoleculeContainer() + leftLabel.leftText = bulletChar + leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) + addView(leftLabel, lastItem: index == list.count - 1) + } } - let lastObj = views.last - MVMCoreUIStackableViewController.populateView(contentView, withUIArray: views) { (obj) -> UIEdgeInsets in - return UIEdgeInsets(top: 0, left: 0, bottom: lastObj?.isEqual(obj) ?? false ? 0 : 16, right: 0) + } + + func addView(_ container: LeftLabelRightMoleculeContainer, lastItem: Bool) { + container.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(container) + let first = reusableViews.first == nil + if first { + pinView(container, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 16) + } else if let previousView = reusableViews.last { + container.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: 16).isActive = true } + pinView(container, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) + pinView(contentView, toView: container, attribute: .trailing, relation: .equal, priority: .required, constant: 0) + if lastItem { + pinView(contentView, toView: container, attribute: .bottom, relation: .equal, priority: .required, constant: 0) + } + reusableViews.append(container) } public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { // This will aggregate names of molecules to make an id. guard let molecules = molecule?.optionalArrayForKey("list") else { - return "stack<>" + return "unordered<>" } - var name = "stack<" + var name = "unordered<" for case let item as [AnyHashable: Any] in molecules { - if let molecule = item.optionalDictionaryForKey(KeyMolecule), let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) { + if let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? item.optionalStringForKey(KeyMoleculeName) { name.append(moleculeName + ",") } } @@ -124,26 +136,36 @@ open class BulletList: Container { return name } + public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + guard let items = json?.optionalArrayForKey("list") else { + return 0 + } + var estimatedHeight: CGFloat = 0 + for case let item as [AnyHashable: AnyHashable] in items { + if let _ = item.optionalStringForKey(KeyMoleculeName) { + let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.estimatedHeight?(forRow: item, delegateObject: delegateObject) + estimatedHeight += ((height ?? 0) + 16) + } + } + return estimatedHeight + } + public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { guard let items = json?.optionalArrayForKey("list") else { return nil } var modules: [String] = [] for case let item as [AnyHashable: AnyHashable] in items { - if let molecule = item.optionalDictionaryForKey(KeyMolecule), let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.requiredModules?(molecule, delegateObject: delegateObject, error: error) { + if let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.requiredModules?(item, delegateObject: delegateObject, error: error) { modules += modulesForMolecule } } return modules.count > 0 ? modules : nil } - - func leftItem(_ string: String) -> [String: Any] { - return ["moleculeName":"label","text":string, "fontStyle":"B2"] - } } -class LeftLabelRightContainer: View { +class LeftLabelRightMoleculeContainer: View { var label = Label.commonLabelB2(true) var rightContainer = MVMCoreUICommonViewsUtility.commonView() @@ -151,6 +173,7 @@ class LeftLabelRightContainer: View { var rightMoleculeName: String? var rightMolecule: View? let containerHelper = ContainerHelper() + var leftText: String? var constraintBtwViews: NSLayoutConstraint? var spaceBtwViews: CGFloat = 8 { @@ -162,6 +185,24 @@ class LeftLabelRightContainer: View { } } + // MARK: - Inits + public override init() { + super.init() + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.init(frame: CGRect.zero) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func setupView() { super.setupView() @@ -173,7 +214,9 @@ class LeftLabelRightContainer: View { addSubview(rightContainer) addSubview(leftContainer) leftContainer.addSubview(label) - NSLayoutConstraint.constraintPinSubview(toSuperview: label) + //NSLayoutConstraint.constraintPinSubview(toSuperview: label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) + leftContainer.leftAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor).isActive = true NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true @@ -184,10 +227,10 @@ class LeftLabelRightContainer: View { constraintBtwViews?.isActive = true //TODO: Need to get confirmation on this - leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true + //leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true setContentHuggingPriority(.defaultHigh, for: .vertical) setContentHuggingPriority(.defaultHigh, for: .horizontal) - rightContainer.setContentHuggingPriority(.defaultHigh, for: .vertical) + rightContainer.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) label.setContentHuggingPriority(.defaultHigh, for: .horizontal) @@ -197,23 +240,31 @@ class LeftLabelRightContainer: View { override func updateView(_ size: CGFloat) { super.updateView(size) + rightMolecule?.updateView(size) + label.updateView(size) + } + + override func reset() { + super.reset() + rightMolecule?.reset() } override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) let previousMoleculeName = rightMoleculeName - guard let moleculeJSON = json?.optionalDictionaryForKey("right") else { - removeSubviewsInRightContainer() + removeSubviewsInRightContainer() + guard let moleculeJSON = json, let _ = moleculeJSON.optionalStringForKey(KeyMoleculeName) else { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) return } - Label.setUILabel(label, withJSON: json?.optionalDictionaryForKey("left"), delegate: delegateObject, additionalData: additionalData) + label.text = leftText rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) //For reuse purpose check that allready added molecule is same - if rightMolecule != nil && previousMoleculeName == rightMoleculeName { - rightMolecule?.setWithJSON(json?.optionalDictionaryForKey("right"), delegateObject: delegateObject, additionalData: additionalData) + if let rightMolecule = self.rightMolecule, previousMoleculeName == rightMoleculeName { + rightMolecule.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) + addView(rightMolecule) } else { - removeSubviewsInRightContainer() if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { addView(molecule) } From 709277362f6a5a7bc6076d2b6a49a8674a95484e Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Fri, 3 Jan 2020 20:20:23 +0530 Subject: [PATCH 40/59] updated constraints --- MVMCoreUI/Molecules/BulletList.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift index 5cb0dbd4..e5eab994 100644 --- a/MVMCoreUI/Molecules/BulletList.swift +++ b/MVMCoreUI/Molecules/BulletList.swift @@ -92,12 +92,12 @@ open class BulletList: Container { // Adds the molecules and sets the json. for (index, map) in list.enumerated() { if let item = items?[index] { - item.leftText = bulletChar + item.leftText = bulletChar ?? String(index+1) item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) addView(item, lastItem: index == list.count - 1) } else { let leftLabel = LeftLabelRightMoleculeContainer() - leftLabel.leftText = bulletChar + leftLabel.leftText = bulletChar ?? String(index+1) leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) addView(leftLabel, lastItem: index == list.count - 1) } @@ -214,9 +214,16 @@ class LeftLabelRightMoleculeContainer: View { addSubview(rightContainer) addSubview(leftContainer) leftContainer.addSubview(label) - //NSLayoutConstraint.constraintPinSubview(toSuperview: label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - leftContainer.leftAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor).isActive = true + label.rightAnchor.constraint(greaterThanOrEqualTo: leftContainer.leftAnchor).isActive = true + let labelRightAnchor = label.rightAnchor.constraint(equalTo: leftContainer.leftAnchor) + labelRightAnchor.priority = UILayoutPriority(rawValue: 200) + labelRightAnchor.isActive = true + leftContainer.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true + let labelBotAnchor = leftContainer.bottomAnchor.constraint(equalTo: label.bottomAnchor) + labelBotAnchor.priority = UILayoutPriority(rawValue: 200) + labelBotAnchor.isActive = true NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true From f1f34b289307a4318f326010fd09cd8ab6ff65b5 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Sat, 4 Jan 2020 14:26:09 +0530 Subject: [PATCH 41/59] textfield list view and textfield list form controller been moved to mobilefirstframework --- MVMCoreUI.xcodeproj/project.pbxproj | 12 - MVMCoreUI/Molecules/BulletList.swift | 291 ------------------ MVMCoreUI/Molecules/MFTextFieldListView.swift | 143 --------- .../MVMCoreUIMoleculeMappingObject.m | 3 +- .../MVMCoreUIViewControllerMappingObject.m | 1 - .../TextFieldListFormViewController.swift | 65 ---- 6 files changed, 1 insertion(+), 514 deletions(-) delete mode 100644 MVMCoreUI/Molecules/BulletList.swift delete mode 100644 MVMCoreUI/Molecules/MFTextFieldListView.swift delete mode 100644 MVMCoreUI/Templates/TextFieldListFormViewController.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 14506f07..b33ce6e9 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -20,8 +20,6 @@ 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; - 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; }; - 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; }; 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */; }; @@ -32,7 +30,6 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; - C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63D632023BDC3A0008F3B1F /* BulletList.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -223,8 +220,6 @@ 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; - 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = ""; }; - 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; @@ -234,7 +229,6 @@ 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; - C63D632023BDC3A0008F3B1F /* BulletList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulletList.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -586,7 +580,6 @@ D29DF0DF21E418B2003B2FB9 /* Templates */ = { isa = PBXGroup; children = ( - 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */, D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */, D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */, D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */, @@ -624,7 +617,6 @@ D224798D2316A988003FCCF9 /* VerticalCombinationViews */, D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, - 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, D2A514662213885800345BFB /* StandardHeaderView.swift */, @@ -635,7 +627,6 @@ 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, - C63D632023BDC3A0008F3B1F /* BulletList.swift */, ); path = Molecules; sourceTree = ""; @@ -1105,7 +1096,6 @@ D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */, - 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */, D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */, D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */, @@ -1141,7 +1131,6 @@ D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, - 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, @@ -1180,7 +1169,6 @@ 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, - C63D632123BDC3A0008F3B1F /* BulletList.swift in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, diff --git a/MVMCoreUI/Molecules/BulletList.swift b/MVMCoreUI/Molecules/BulletList.swift deleted file mode 100644 index e5eab994..00000000 --- a/MVMCoreUI/Molecules/BulletList.swift +++ /dev/null @@ -1,291 +0,0 @@ -// -// BulletList.swift -// MVMCoreUI -// -// Created by Murugan, Vimal on 02/01/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - -open class BulletList: Container { - - var contentView = MVMCoreUICommonViewsUtility.commonView() - var reusableViews: [LeftLabelRightMoleculeContainer] = [] - var bulletChar: String? - - /// Removes all stack items views from the view. - func removeAllItemInViews() { - reusableViews.forEach({ $0.removeFromSuperview() }) - } - - // MARK: - Inits - public override init() { - super.init() - } - - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.init(frame: CGRect.zero) - setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // MARK: - Helpers - public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { - let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) - constraint.priority = priority - constraint.isActive = true - } - - // MARK: - MFViewProtocol - public override func setupView() { - super.setupView() - guard contentView.superview == nil else { - return - } - MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) - translatesAutoresizingMaskIntoConstraints = false - backgroundColor = .clear - addSubview(contentView) - containerHelper.constrainView(contentView) - contentView.setContentHuggingPriority(.defaultHigh, for: .vertical) - contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal) - } - - public override func updateView(_ size: CGFloat) { - super.updateView(size) - directionalLayoutMargins.leading = 0 - directionalLayoutMargins.trailing = 0 - reusableViews.forEach({ $0.updateView(size) }) - } - - // MARK: - MVMCoreUIMoleculeViewProtocol - public override func reset() { - super.reset() - backgroundColor = .clear - reusableViews.forEach({ $0.reset() }) - } - - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - let previousJSON = self.json - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - removeAllItemInViews() - // If the items in the stack are the same, just update previous items instead of re-allocating. - var items: [LeftLabelRightMoleculeContainer]? - if BulletList.name(forReuse: previousJSON, delegateObject: delegateObject) == BulletList.name(forReuse: json, delegateObject: delegateObject) { - items = self.reusableViews - } - self.reusableViews = [] - - guard let list = json?.arrayForKey("list") as? [[String: Any]] else { - return - } - - bulletChar = json?.optionalStringForKey("bulletChar") - // Adds the molecules and sets the json. - for (index, map) in list.enumerated() { - if let item = items?[index] { - item.leftText = bulletChar ?? String(index+1) - item.setWithJSON(map, delegateObject: delegateObject, additionalData: nil) - addView(item, lastItem: index == list.count - 1) - } else { - let leftLabel = LeftLabelRightMoleculeContainer() - leftLabel.leftText = bulletChar ?? String(index+1) - leftLabel.setWithJSON(map, delegateObject: delegateObject, additionalData: additionalData) - addView(leftLabel, lastItem: index == list.count - 1) - } - } - } - - func addView(_ container: LeftLabelRightMoleculeContainer, lastItem: Bool) { - container.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(container) - let first = reusableViews.first == nil - if first { - pinView(container, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 16) - } else if let previousView = reusableViews.last { - container.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: 16).isActive = true - } - pinView(container, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) - pinView(contentView, toView: container, attribute: .trailing, relation: .equal, priority: .required, constant: 0) - if lastItem { - pinView(contentView, toView: container, attribute: .bottom, relation: .equal, priority: .required, constant: 0) - } - reusableViews.append(container) - } - - public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { - // This will aggregate names of molecules to make an id. - guard let molecules = molecule?.optionalArrayForKey("list") else { - return "unordered<>" - } - var name = "unordered<" - for case let item as [AnyHashable: Any] in molecules { - if let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? item.optionalStringForKey(KeyMoleculeName) { - name.append(moleculeName + ",") - } - } - name.append(">") - return name - } - - public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - guard let items = json?.optionalArrayForKey("list") else { - return 0 - } - var estimatedHeight: CGFloat = 0 - for case let item as [AnyHashable: AnyHashable] in items { - if let _ = item.optionalStringForKey(KeyMoleculeName) { - let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.estimatedHeight?(forRow: item, delegateObject: delegateObject) - estimatedHeight += ((height ?? 0) + 16) - } - } - return estimatedHeight - } - - public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let items = json?.optionalArrayForKey("list") else { - return nil - } - var modules: [String] = [] - for case let item as [AnyHashable: AnyHashable] in items { - if let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: item)?.requiredModules?(item, delegateObject: delegateObject, error: error) { - modules += modulesForMolecule - } - } - return modules.count > 0 ? modules : nil - } - -} - -class LeftLabelRightMoleculeContainer: View { - - var label = Label.commonLabelB2(true) - var rightContainer = MVMCoreUICommonViewsUtility.commonView() - var leftContainer = MVMCoreUICommonViewsUtility.commonView() - var rightMoleculeName: String? - var rightMolecule: View? - let containerHelper = ContainerHelper() - var leftText: String? - - var constraintBtwViews: NSLayoutConstraint? - var spaceBtwViews: CGFloat = 8 { - didSet { - if spaceBtwViews != oldValue { - constraintBtwViews?.constant = spaceBtwViews - layoutIfNeeded() - } - } - } - - // MARK: - Inits - public override init() { - super.init() - } - - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.init(frame: CGRect.zero) - setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func setupView() { - super.setupView() - - guard rightContainer.superview == nil else { - return - } - - translatesAutoresizingMaskIntoConstraints = false - addSubview(rightContainer) - addSubview(leftContainer) - leftContainer.addSubview(label) - - NSLayoutConstraint.constraintPinSubview(label, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - label.rightAnchor.constraint(greaterThanOrEqualTo: leftContainer.leftAnchor).isActive = true - let labelRightAnchor = label.rightAnchor.constraint(equalTo: leftContainer.leftAnchor) - labelRightAnchor.priority = UILayoutPriority(rawValue: 200) - labelRightAnchor.isActive = true - leftContainer.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true - let labelBotAnchor = leftContainer.bottomAnchor.constraint(equalTo: label.bottomAnchor) - labelBotAnchor.priority = UILayoutPriority(rawValue: 200) - labelBotAnchor.isActive = true - - NSLayoutConstraint.constraintPinSubview(leftContainer, pinTop: true, pinBottom: false, pinLeft: true, pinRight: false) - bottomAnchor.constraint(greaterThanOrEqualTo: leftContainer.bottomAnchor).isActive = true - - NSLayoutConstraint.constraintPinSubview(rightContainer, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) - constraintBtwViews = rightContainer.leftAnchor.constraint(equalTo: leftContainer.rightAnchor, constant: spaceBtwViews) - constraintBtwViews?.priority = .required - constraintBtwViews?.isActive = true - - //TODO: Need to get confirmation on this - //leftContainer.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.05, constant: 0).isActive = true - setContentHuggingPriority(.defaultHigh, for: .vertical) - setContentHuggingPriority(.defaultHigh, for: .horizontal) - rightContainer.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) - rightContainer.setContentHuggingPriority(.defaultHigh, for: .horizontal) - - label.setContentHuggingPriority(.defaultHigh, for: .horizontal) - label.setContentHuggingPriority(.defaultHigh, for: .vertical) - - } - - override func updateView(_ size: CGFloat) { - super.updateView(size) - rightMolecule?.updateView(size) - label.updateView(size) - } - - override func reset() { - super.reset() - rightMolecule?.reset() - } - - override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - let previousMoleculeName = rightMoleculeName - removeSubviewsInRightContainer() - guard let moleculeJSON = json, let _ = moleculeJSON.optionalStringForKey(KeyMoleculeName) else { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - return - } - - label.text = leftText - rightMoleculeName = moleculeJSON.optionalStringForKey(KeyMoleculeName) - //For reuse purpose check that allready added molecule is same - if let rightMolecule = self.rightMolecule, previousMoleculeName == rightMoleculeName { - rightMolecule.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) - addView(rightMolecule) - } else { - if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) { - addView(molecule) - } - } - } - - func removeSubviewsInRightContainer() { - rightContainer.subviews.forEach({ $0.removeFromSuperview() }) - } - - func addView(_ view: UIView) { - view.translatesAutoresizingMaskIntoConstraints = false - rightContainer.addSubview(view) - containerHelper.constrainView(view) - rightMolecule = view as? View - } -} diff --git a/MVMCoreUI/Molecules/MFTextFieldListView.swift b/MVMCoreUI/Molecules/MFTextFieldListView.swift deleted file mode 100644 index c695c3a3..00000000 --- a/MVMCoreUI/Molecules/MFTextFieldListView.swift +++ /dev/null @@ -1,143 +0,0 @@ -// -// MFTextFieldListView.swift -// MobileFirstFramework -// -// Created by Suresh, Kamlesh on 9/21/18. -// Copyright © 2018 Verizon Wireless. All rights reserved. -// - -import UIKit -import MVMCore - -@objc public protocol TextFieldListHelperProtocol { - @objc optional func fieldForMap(_ map: [String: Any], textField: MFTextField) - @objc optional func spaceBetweenField() -> CGFloat -} - -public class MFTextFieldListView: ViewConstrainingView { - - public var textFieldMapList: [[String: Any]]? - public var parentViewContoller: MFViewController? - public var textFieldsToValidate: [MFTextField] = [] - public var textFields: [MFTextField] = [] - public var primaryButton: PrimaryButton? - - public init(textFieldMapList: [[String: Any]], parentViewContoller: MFViewController, primaryButton: PrimaryButton?) { - self.textFieldMapList = textFieldMapList - self.parentViewContoller = parentViewContoller - self.primaryButton = primaryButton - super.init(frame: .zero) - } - - public required init?(coder decoder: NSCoder) { - super.init(coder: decoder) - } - - public override func updateView(_ size: CGFloat) { - super.updateView(size) - for textField in textFields { - textField.updateView(size) - } - } - - public override func setupView() { - super.setupView() - self.translatesAutoresizingMaskIntoConstraints = false - - guard let textFieldMapList = textFieldMapList else { - return - } - var viewList: [UIView] = [] - - for textFieldMap in textFieldMapList { - if let textField = getTextFieldForMap(textFieldMap) { - - (parentViewContoller as? TextFieldListHelperProtocol)?.fieldForMap?(textFieldMap, textField: textField) - - if textFieldMap.boolForKey("required") { - textFieldsToValidate.append(textField) - } - - textFields.append(textField) - if let fieldKey = textField.fieldKey { - parentViewContoller?.register(textField, forErrorKey: fieldKey as String) - } - viewList.append(textField) - } - } - - let spaceBtwField = (parentViewContoller as? TextFieldListHelperProtocol)?.spaceBetweenField?() ?? 0.0 - StackableViewController.populateView(self, withUIArray: viewList) { (viewObject) -> UIEdgeInsets in - var edgeInsets = StackableViewController.standardSpaceAroundUIObject() - edgeInsets.left = 0 - edgeInsets.right = 0 - edgeInsets.top = 0 - edgeInsets.bottom = spaceBtwField - return edgeInsets - } - - primaryButton?.handleEnabling(with: textFieldsToValidate) - } - - public func addParams(requestParameters: MVMCoreRequestParameters) { - requestParameters.add(getTextParamsList()) - } - - public func getTextParamsList() -> [String: Any] { - return DispatchQueue.main.sync { - var extraParam: [String: Any] = [:] - for textField in textFields { - if let fieldKey = textField.fieldKey { - extraParam[fieldKey as String] = textField.text ?? "" - } - } - return extraParam - } - } - - private func getTextFieldForMap(_ map: [String: Any]) -> MFTextField? { - if map.boolForKey("dropDown") { - let dropDownFld = DropDown(map: map, bothDelegates: self) - dropDownFld?.setWithJSON(map, delegateObject: parentViewContoller?.delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) - dropDownFld?.showDropDown(true) - return dropDownFld - } - return MFTextField(map: map, bothDelegates: self) - } -} - -extension MFTextFieldListView: UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate { - @objc open func textFieldDidEndEditing(_ textField: UITextField) { - parentViewContoller?.textFieldDidEndEditing(textField) - primaryButton?.handleEnabling(with: textFieldsToValidate) - } - - @objc open func dismissFieldInput(_ sender: Any?) { - parentViewContoller?.dismissFieldInput(sender) - } - - @objc open func textFieldShouldReturn(_ textField: UITextField) -> Bool { - textField.resignFirstResponder() - return true - } - - @objc open func textFieldDidBeginEditing(_ textField: UITextField) { - parentViewContoller?.textFieldDidBeginEditing(textField) - } - - @objc open func entryIsValid(_ textfield: MFTextField?) { - DispatchQueue.main.async { - if self.parentViewContoller?.responds(to: #selector(MFTextFieldDelegate.entryIsValid(_:))) ?? false { - self.parentViewContoller?.entryIsValid(textfield) - } - } - } - - @objc open func entryIsInvalid(_ textfield: MFTextField?) { - DispatchQueue.main.async { - if self.parentViewContoller?.responds(to: #selector(MFTextFieldDelegate.entryIsInvalid(_:))) ?? false { - self.parentViewContoller?.entryIsInvalid(textfield) - } - } - } -} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 47bbac98..9db7822d 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -66,8 +66,7 @@ @"tabsListItem": TabsTableViewCell.class, @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, - @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class, - @"bulletList": BulletList.class + @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class } mutableCopy]; }); return mapping; diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index e770ede5..2bc1a0dd 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -19,7 +19,6 @@ static NSMutableDictionary *viewControllerMapping; dispatch_once(&onceToken, ^{ viewControllerMapping = [@{ - @"textFieldListForm" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[TextFieldListFormViewController class]], @"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], diff --git a/MVMCoreUI/Templates/TextFieldListFormViewController.swift b/MVMCoreUI/Templates/TextFieldListFormViewController.swift deleted file mode 100644 index c0509679..00000000 --- a/MVMCoreUI/Templates/TextFieldListFormViewController.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// MVMCoreUITextFormViewController.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 1/24/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import UIKit - -open class TextFieldListFormViewController: TopLabelsAndBottomButtonsViewController, TextFieldListHelperProtocol { - - - public var textFieldListView: MFTextFieldListView? - - open override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - open override func updateViews() { - super.updateViews() - } - - open override func newDataBuildScreen() { - super.newDataBuildScreen() - topLabelsView?.separatorView?.isHidden = true - } - - open override func buildViewsBetweenLabelsAndButtons() -> [UIView]? { - var viewList: [UIView] = [] - - if let textFieldsList = textFieldsLists() { - let textFieldListView = MFTextFieldListView(textFieldMapList: textFieldsList, - parentViewContoller: self, - primaryButton: self.primaryButton) - self.textFieldListView = textFieldListView - viewList.append(textFieldListView) - } - return viewList - } - - open override func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { - textFieldListView?.addParams(requestParameters: requestParameters) - super.handleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData) - } - - open override func spaceAboveBetweenView() -> NSNumber? { - return PaddingFour as NSNumber - } - - open func textFieldsLists() -> [[String: Any]]? { - return loadObject?.pageJSON?.arrayForKey("textFieldList") as? [[String: Any]] - } - - //MARK: - Textfield list protocol - open func spaceBetweenField() -> CGFloat { - return 0.0 - } - - open func fieldForMap(_ map: [String : Any], textField: MFTextField) { - - } - -} From bf0b2ecb79006741993e4b58ae75a033e0cdf864 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Mon, 6 Jan 2020 16:49:03 +0530 Subject: [PATCH 42/59] changed separator style to thin --- MVMCoreUI/Molecules/Items/TableViewCell.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/Molecules/Items/TableViewCell.swift index f1fb3519..b1aa92a5 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TableViewCell.swift @@ -70,14 +70,14 @@ import UIKit topMarginPadding = 48 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .standard + bottomSeparatorView?.style = .thin } open func styleShortDivider() { topMarginPadding = 32 bottomMarginPadding = 16 topSeparatorView?.style = .none - bottomSeparatorView?.style = .standard + bottomSeparatorView?.style = .thin } open func styleFooter() { From 129a0e92411eef785faafa6639d907722d867094 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Tue, 7 Jan 2020 12:34:29 +0530 Subject: [PATCH 43/59] New molecule -> headLineBodyCaretLinkImage --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + .../HeadLineBodyCaretLinkImage.swift | 95 +++++++++++++++++++ .../MVMCoreUIMoleculeMappingObject.m | 3 +- 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c26f4c..775b8b0d 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -233,6 +234,7 @@ 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadLineBodyCaretLinkImage.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -486,6 +488,7 @@ D2A638FC22CA98280052ED1F /* HeadlineBody.swift */, D22479952316AF6D003FCCF9 /* HeadlineBodyTextButton.swift */, D27CD40F2339057800C1DC07 /* EyebrowHeadlineBodyLink.swift */, + C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */, ); path = VerticalCombinationViews; sourceTree = ""; @@ -1175,6 +1178,7 @@ 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, D268C712238D6699007F2C1C /* DropDown.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, + C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift new file mode 100644 index 00000000..107ca07f --- /dev/null +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -0,0 +1,95 @@ +// +// HeadLineBodyCaretLinkImage.swift +// MVMCoreUI +// +// Created by Arora, Prateek on 06/01/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers public class HeadLineBodyCaretLinkImage: ViewConstrainingView { + + let headlineBody = HeadlineBody(frame: .zero) + let caretButton = CaretButton(frame: .zero) + //let caretButton = MFTextButton(nil, constrainHeight: true, forWidth: MVMCoreUIUtility.getWidth()) + + let backgroundImageView = MFLoadImageView() + var spaceBetweenConstant: CGFloat = 104.0 + var spaceBetweenViews: NSLayoutConstraint? + var leftConstant: CGFloat = 32.0 + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + headlineBody.updateView(size) + caretButton.updateView(size) + backgroundImageView.updateView(size) + setSpacing() + } + + open override func setupView() { + super.setupView() + guard subviews.count == 0 else { + return + } + let view = MVMCoreUICommonViewsUtility.commonView() + addSubview(view) + pinView(toSuperView: view) + + view.addSubview(headlineBody) + view.addSubview(caretButton) + + headlineBody.translatesAutoresizingMaskIntoConstraints = false + headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: 24.0).isActive = true + headlineBody.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true + var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) + constraint.priority = .defaultHigh + constraint.isActive = true + + spaceBetweenViews = caretButton.topAnchor.constraint(equalTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) + spaceBetweenViews?.isActive = true + + caretButton.translatesAutoresizingMaskIntoConstraints = false + caretButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true + view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true + view.rightAnchor.constraint(greaterThanOrEqualTo: caretButton.rightAnchor).isActive = true + constraint = view.rightAnchor.constraint(equalTo: caretButton.rightAnchor) + constraint.priority = .defaultHigh + constraint.isActive = true + + //Background image view + backgroundImageView.translatesAutoresizingMaskIntoConstraints = false + backgroundImageView.imageView.contentMode = .scaleAspectFill + view.addSubview(backgroundImageView) + NSLayoutConstraint.constraintPinSubview(toSuperview: backgroundImageView) + view.sendSubviewToBack(backgroundImageView) + } + + // MARK: - Constraining + public func setSpacing() { + if headlineBody.hasText() && (caretButton.titleLabel?.text?.count ?? 0) > 0 { + spaceBetweenViews?.constant = spaceBetweenConstant + } else { + spaceBetweenViews?.constant = 0 + } + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + if let imageJSON = json?.optionalDictionaryForKey("image") { + backgroundImageView.setWithJSON(imageJSON, delegateObject: delegateObject, additionalData: additionalData) + } + headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) + caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) + + } + + open override func reset() { + super.reset() + headlineBody.reset() + } + + public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 320 + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 9db7822d..ecad0fc7 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -66,7 +66,8 @@ @"tabsListItem": TabsTableViewCell.class, @"dropDownListItem": DropDownFilterTableViewCell.class, @"headlineBodyButton": HeadlineBodyButton.class, - @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class + @"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class, + @"headLineBodyCaretLinkImage" : HeadLineBodyCaretLinkImage.class } mutableCopy]; }); return mapping; From d891d7ba1a88bfeb5b3ab88140bfbae7c1e255b5 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Tue, 7 Jan 2020 19:29:26 +0530 Subject: [PATCH 44/59] Code cleaning --- .../HeadLineBodyCaretLinkImage.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 107ca07f..5347b730 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -17,6 +17,8 @@ import Foundation var spaceBetweenConstant: CGFloat = 104.0 var spaceBetweenViews: NSLayoutConstraint? var leftConstant: CGFloat = 32.0 + var leftConstraint: NSLayoutConstraint? + // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) @@ -38,6 +40,7 @@ import Foundation view.addSubview(headlineBody) view.addSubview(caretButton) + //Headline view headlineBody.translatesAutoresizingMaskIntoConstraints = false headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: 24.0).isActive = true headlineBody.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true @@ -48,6 +51,7 @@ import Foundation spaceBetweenViews = caretButton.topAnchor.constraint(equalTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) spaceBetweenViews?.isActive = true + //Caret view caretButton.translatesAutoresizingMaskIntoConstraints = false caretButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true @@ -76,17 +80,15 @@ import Foundation // MARK: - MVMCoreUIMoleculeViewProtocol open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - if let imageJSON = json?.optionalDictionaryForKey("image") { - backgroundImageView.setWithJSON(imageJSON, delegateObject: delegateObject, additionalData: additionalData) - } + backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData) headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) - } open override func reset() { super.reset() headlineBody.reset() + backgroundImageView.reset() } public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { From f32cc7d05c8e618703209fede23cecf308b5204f Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Wed, 8 Jan 2020 12:21:28 +0530 Subject: [PATCH 45/59] Code cleaning --- .../HeadLineBodyCaretLinkImage.swift | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 5347b730..53bff16d 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -11,14 +11,11 @@ import Foundation let headlineBody = HeadlineBody(frame: .zero) let caretButton = CaretButton(frame: .zero) - //let caretButton = MFTextButton(nil, constrainHeight: true, forWidth: MVMCoreUIUtility.getWidth()) - let backgroundImageView = MFLoadImageView() var spaceBetweenConstant: CGFloat = 104.0 var spaceBetweenViews: NSLayoutConstraint? var leftConstant: CGFloat = 32.0 - var leftConstraint: NSLayoutConstraint? - + // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) @@ -36,7 +33,6 @@ import Foundation let view = MVMCoreUICommonViewsUtility.commonView() addSubview(view) pinView(toSuperView: view) - view.addSubview(headlineBody) view.addSubview(caretButton) @@ -80,9 +76,9 @@ import Foundation // MARK: - MVMCoreUIMoleculeViewProtocol open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData) - headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) - caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) + backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData) + headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) + caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) } open override func reset() { From c908606b79db06142375a0117644e7327a456e18 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Wed, 8 Jan 2020 13:08:09 +0530 Subject: [PATCH 46/59] Review Comment Changes --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 53bff16d..d1710070 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -44,7 +44,7 @@ import Foundation constraint.priority = .defaultHigh constraint.isActive = true - spaceBetweenViews = caretButton.topAnchor.constraint(equalTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) + spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) spaceBetweenViews?.isActive = true //Caret view From 4c60ea2f1f39ba5df18b23b8bfd6c7375b1f952d Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Wed, 8 Jan 2020 14:53:59 +0530 Subject: [PATCH 47/59] Review comment changes --- .../HeadLineBodyCaretLinkImage.swift | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index d1710070..54f9b357 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -17,14 +17,6 @@ import Foundation var leftConstant: CGFloat = 32.0 // MARK: - MVMCoreViewProtocol - open override func updateView(_ size: CGFloat) { - super.updateView(size) - headlineBody.updateView(size) - caretButton.updateView(size) - backgroundImageView.updateView(size) - setSpacing() - } - open override func setupView() { super.setupView() guard subviews.count == 0 else { @@ -33,15 +25,15 @@ import Foundation let view = MVMCoreUICommonViewsUtility.commonView() addSubview(view) pinView(toSuperView: view) + setSpacing() view.addSubview(headlineBody) view.addSubview(caretButton) //Headline view - headlineBody.translatesAutoresizingMaskIntoConstraints = false headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: 24.0).isActive = true headlineBody.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) - constraint.priority = .defaultHigh + constraint.priority = .defaultLow constraint.isActive = true spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) @@ -53,7 +45,7 @@ import Foundation view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true view.rightAnchor.constraint(greaterThanOrEqualTo: caretButton.rightAnchor).isActive = true constraint = view.rightAnchor.constraint(equalTo: caretButton.rightAnchor) - constraint.priority = .defaultHigh + constraint.priority = .defaultLow constraint.isActive = true //Background image view From 0226eb2cace3e5dac857045f92ed83870b742e76 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Wed, 8 Jan 2020 18:46:02 +0530 Subject: [PATCH 48/59] Review comments : added default padding --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 54f9b357..469a4615 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -30,7 +30,7 @@ import Foundation view.addSubview(caretButton) //Headline view - headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: 24.0).isActive = true + headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true headlineBody.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) constraint.priority = .defaultLow From 203484b2883110bde3931dec39ee3ef6ffa23dd8 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Wed, 8 Jan 2020 18:49:36 +0530 Subject: [PATCH 49/59] Code clean --- .../HeadLineBodyCaretLinkImage.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 469a4615..e10a6196 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -17,6 +17,13 @@ import Foundation var leftConstant: CGFloat = 32.0 // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + headlineBody.updateView(size) + caretButton.updateView(size) + backgroundImageView.updateView(size) + } + open override func setupView() { super.setupView() guard subviews.count == 0 else { From 67304b7657d36f2fe6d526cc610e39f30c6f2531 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 13:26:09 +0530 Subject: [PATCH 50/59] Changes as suggested by Ryan --- .../HeadLineBodyCaretLinkImage.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index e10a6196..4c8d2313 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -15,13 +15,17 @@ import Foundation var spaceBetweenConstant: CGFloat = 104.0 var spaceBetweenViews: NSLayoutConstraint? var leftConstant: CGFloat = 32.0 - + var leftConstraintHeadline : NSLayoutConstraint? + var leftConstraintCaretView : NSLayoutConstraint? + let padding = MFStyler.defaultHorizontalPaddingForApplicationWidth() // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) headlineBody.updateView(size) caretButton.updateView(size) backgroundImageView.updateView(size) + leftConstraintHeadline?.constant = MFStyler.defaultHorizontalPadding(forSize: size) + leftConstraintCaretView?.constant = MFStyler.defaultHorizontalPadding(forSize: size) } open override func setupView() { @@ -37,8 +41,9 @@ import Foundation view.addSubview(caretButton) //Headline view + leftConstraintHeadline = headlineBody.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) + leftConstraintHeadline?.isActive = true headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true - headlineBody.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) constraint.priority = .defaultLow constraint.isActive = true @@ -48,7 +53,9 @@ import Foundation //Caret view caretButton.translatesAutoresizingMaskIntoConstraints = false - caretButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: leftConstant).isActive = true + leftConstraintCaretView = caretButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) + leftConstraintCaretView?.isActive = true + caretButton.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: PaddingDefault).isActive = true view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true view.rightAnchor.constraint(greaterThanOrEqualTo: caretButton.rightAnchor).isActive = true constraint = view.rightAnchor.constraint(equalTo: caretButton.rightAnchor) From 03aeb1fc63958bd3891afebdb0fa84b494ad31a8 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 16:35:56 +0530 Subject: [PATCH 51/59] headline body width 85% having max as 350px --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 4c8d2313..08ea4b5b 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -18,6 +18,7 @@ import Foundation var leftConstraintHeadline : NSLayoutConstraint? var leftConstraintCaretView : NSLayoutConstraint? let padding = MFStyler.defaultHorizontalPaddingForApplicationWidth() + let maxWidth : CGFloat = 350.0 // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) @@ -44,6 +45,9 @@ import Foundation leftConstraintHeadline = headlineBody.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) leftConstraintHeadline?.isActive = true headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true + let headLineBodyWidth = min((MVMCoreUISplitViewController.getDetailViewWidth() * 0.85), maxWidth) + headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: headLineBodyWidth).isActive = true + var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) constraint.priority = .defaultLow constraint.isActive = true From 7b49224abdf948a7517e12e6922a161e05e2adb5 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 18:19:52 +0530 Subject: [PATCH 52/59] Caret link bottom spacing --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 08ea4b5b..854c6a31 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -14,7 +14,6 @@ import Foundation let backgroundImageView = MFLoadImageView() var spaceBetweenConstant: CGFloat = 104.0 var spaceBetweenViews: NSLayoutConstraint? - var leftConstant: CGFloat = 32.0 var leftConstraintHeadline : NSLayoutConstraint? var leftConstraintCaretView : NSLayoutConstraint? let padding = MFStyler.defaultHorizontalPaddingForApplicationWidth() @@ -52,7 +51,7 @@ import Foundation constraint.priority = .defaultLow constraint.isActive = true - spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) + spaceBetweenViews = caretButton.topAnchor.constraint(equalTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) spaceBetweenViews?.isActive = true //Caret view From b8a162da54f71396f199a289f64accdde7cd4ddb Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 20:10:17 +0530 Subject: [PATCH 53/59] Code cleaning removing duplicate constraint --- .../HeadLineBodyCaretLinkImage.swift | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 854c6a31..3ff09aa9 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -36,7 +36,7 @@ import Foundation let view = MVMCoreUICommonViewsUtility.commonView() addSubview(view) pinView(toSuperView: view) - setSpacing() + //setSpacing() view.addSubview(headlineBody) view.addSubview(caretButton) @@ -46,12 +46,8 @@ import Foundation headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true let headLineBodyWidth = min((MVMCoreUISplitViewController.getDetailViewWidth() * 0.85), maxWidth) headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: headLineBodyWidth).isActive = true - - var constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) - constraint.priority = .defaultLow - constraint.isActive = true - spaceBetweenViews = caretButton.topAnchor.constraint(equalTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) + spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) spaceBetweenViews?.isActive = true //Caret view @@ -60,8 +56,8 @@ import Foundation leftConstraintCaretView?.isActive = true caretButton.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: PaddingDefault).isActive = true view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true - view.rightAnchor.constraint(greaterThanOrEqualTo: caretButton.rightAnchor).isActive = true - constraint = view.rightAnchor.constraint(equalTo: caretButton.rightAnchor) + + let constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) constraint.priority = .defaultLow constraint.isActive = true From 20f62ce4c5f393a114e838ba33c408d264cf607e Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 20:10:39 +0530 Subject: [PATCH 54/59] Code clean --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 3ff09aa9..f1695d02 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -36,7 +36,6 @@ import Foundation let view = MVMCoreUICommonViewsUtility.commonView() addSubview(view) pinView(toSuperView: view) - //setSpacing() view.addSubview(headlineBody) view.addSubview(caretButton) From b037d23adbaea3f428348bba75de88125e4c75a3 Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Thu, 9 Jan 2020 22:25:53 +0530 Subject: [PATCH 55/59] Code changes --- .../HeadLineBodyCaretLinkImage.swift | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index f1695d02..1b1c57e9 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -43,9 +43,12 @@ import Foundation leftConstraintHeadline = headlineBody.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) leftConstraintHeadline?.isActive = true headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true - let headLineBodyWidth = min((MVMCoreUISplitViewController.getDetailViewWidth() * 0.85), maxWidth) - headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: headLineBodyWidth).isActive = true - + + let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85) + headLineBodyWidth.priority = .defaultHigh + headLineBodyWidth.isActive = true + headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true + spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) spaceBetweenViews?.isActive = true @@ -67,16 +70,7 @@ import Foundation NSLayoutConstraint.constraintPinSubview(toSuperview: backgroundImageView) view.sendSubviewToBack(backgroundImageView) } - - // MARK: - Constraining - public func setSpacing() { - if headlineBody.hasText() && (caretButton.titleLabel?.text?.count ?? 0) > 0 { - spaceBetweenViews?.constant = spaceBetweenConstant - } else { - spaceBetweenViews?.constant = 0 - } - } - + // MARK: - MVMCoreUIMoleculeViewProtocol open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) From 61d36b25a79cf2f1c095d9dba0e409ff376f716d Mon Sep 17 00:00:00 2001 From: "Arora, Prateek" Date: Fri, 10 Jan 2020 11:04:07 +0530 Subject: [PATCH 56/59] Code changes --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 1b1c57e9..33492541 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -56,10 +56,9 @@ import Foundation caretButton.translatesAutoresizingMaskIntoConstraints = false leftConstraintCaretView = caretButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) leftConstraintCaretView?.isActive = true - caretButton.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: PaddingDefault).isActive = true view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true - let constraint = view.rightAnchor.constraint(equalTo: headlineBody.rightAnchor) + let constraint = view.rightAnchor.constraint(greaterThanOrEqualTo: headlineBody.rightAnchor) constraint.priority = .defaultLow constraint.isActive = true From 7a48633cce0e2f1f3879cb0477607d8738cc11b8 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 10 Jan 2020 10:59:13 -0500 Subject: [PATCH 57/59] Implemented Ryan's feedback, as Prateek is out of office for next week. --- .../HeadLineBodyCaretLinkImage.swift | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 33492541..80eaf69e 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -13,7 +13,6 @@ import Foundation let caretButton = CaretButton(frame: .zero) let backgroundImageView = MFLoadImageView() var spaceBetweenConstant: CGFloat = 104.0 - var spaceBetweenViews: NSLayoutConstraint? var leftConstraintHeadline : NSLayoutConstraint? var leftConstraintCaretView : NSLayoutConstraint? let padding = MFStyler.defaultHorizontalPaddingForApplicationWidth() @@ -48,9 +47,6 @@ import Foundation headLineBodyWidth.priority = .defaultHigh headLineBodyWidth.isActive = true headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true - - spaceBetweenViews = caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant) - spaceBetweenViews?.isActive = true //Caret view caretButton.translatesAutoresizingMaskIntoConstraints = false @@ -58,9 +54,7 @@ import Foundation leftConstraintCaretView?.isActive = true view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true - let constraint = view.rightAnchor.constraint(greaterThanOrEqualTo: headlineBody.rightAnchor) - constraint.priority = .defaultLow - constraint.isActive = true + caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true //Background image view backgroundImageView.translatesAutoresizingMaskIntoConstraints = false From c4112665d9ba4b4ab58686ee5ea52fdd086eabdf Mon Sep 17 00:00:00 2001 From: panxi Date: Fri, 10 Jan 2020 11:35:29 -0500 Subject: [PATCH 58/59] add bottom padding --- .../VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 80eaf69e..9c3dba8a 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -52,7 +52,7 @@ import Foundation caretButton.translatesAutoresizingMaskIntoConstraints = false leftConstraintCaretView = caretButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding) leftConstraintCaretView?.isActive = true - view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor).isActive = true + view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: PaddingDefault).isActive = true caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true From 85f210abe8397b69585ffab06eb4be87ce3d0646 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 13 Jan 2020 08:49:51 -0500 Subject: [PATCH 59/59] Accessibility fixes. --- MVMCoreUI/Atoms/Views/Label.swift | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 56a0c38b..30101710 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -91,6 +91,7 @@ public typealias ActionBlock = () -> () translatesAutoresizingMaskIntoConstraints = false clauses = [] accessibilityCustomActions = [] + accessibilityTraits = .staticText let tapGesture = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped(_:))) tapGesture.numberOfTapsRequired = 1 @@ -522,6 +523,7 @@ public typealias ActionBlock = () -> () func appendActionableClause(range: NSRange, actionBlock: @escaping ActionBlock) { + accessibilityTraits = .button let accessibleAction = customAccessibilityAction(range: range) clauses.append(ActionableClause(range: range, actionBlock: actionBlock, accessibilityID: accessibleAction?.hash ?? -1)) } @@ -582,6 +584,7 @@ extension Label { styleB2(true) accessibilityCustomActions = [] clauses = [] + accessibilityTraits = .staticText } @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @@ -721,7 +724,6 @@ extension UITapGestureRecognizer { if label.makeWholeViewClickable { return true } - guard let abstractContainer = label.abstractTextContainer() else { return false } let textContainer = abstractContainer.0 let layoutManager = abstractContainer.1 @@ -775,7 +777,7 @@ extension Label { } @objc public func accessibilityCustomAction(_ action: UIAccessibilityCustomAction) { - + for clause in clauses { if action.hash == clause.accessibilityID { clause.performAction() @@ -783,4 +785,19 @@ extension Label { } } } + + open override func accessibilityActivate() -> Bool { + + guard let accessibleActions = accessibilityCustomActions else { return false } + + for clause in clauses { + for action in accessibleActions { + if action.hash == clause.accessibilityID { + clause.performAction() + return true + } + } + } + return false + } }