From 8572b1c71840a059f666d9569b399266bbe669b7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 10 Apr 2020 16:03:01 -0400 Subject: [PATCH 01/51] current state --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++ .../TextFields/BaseDropdownEntryField.swift | 8 +-- .../Atomic/Atoms/TextFields/EntryField.swift | 10 ++-- .../Atoms/TextFields/TextEntryField.swift | 57 ++++++++++++++----- .../Extensions/UIToolbar+Extension.swift | 36 ++++++++++++ 5 files changed, 89 insertions(+), 26 deletions(-) create mode 100644 MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b96efb29..7ac8ba76 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,6 +95,7 @@ 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 0A7ECC5D243CE85300C828E8 /* DoughnutChartItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */; }; 0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */; }; + 0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */; }; 0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */; }; 0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; }; 0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; }; @@ -504,6 +505,7 @@ 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxLabel.swift; sourceTree = ""; }; 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoughnutChartItemModel.swift; sourceTree = ""; }; 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorViewWithLabel.swift; sourceTree = ""; }; + 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIToolbar+Extension.swift"; sourceTree = ""; }; 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = ""; }; 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = ""; }; @@ -1083,6 +1085,7 @@ D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */, D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */, 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */, + 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */, ); path = Extensions; sourceTree = ""; @@ -2125,6 +2128,7 @@ BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */, D2B18B812360945C00A9AEDC /* View.swift in Sources */, C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */, + 0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */, 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift index f7083df5..bf1dbfab 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift @@ -64,13 +64,7 @@ import UIKit super.setupFieldContainerContent(container) container.addSubview(dropDownCaretView) - - textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6) - textFieldTrailingConstraint?.isActive = true - - container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true - dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true + accessoryView = dropDownCaretView } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 658af357..2487d619 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -36,7 +36,7 @@ import UIKit label.setContentCompressionResistancePriority(.required, for: .vertical) return label }() - + //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- @@ -193,7 +193,7 @@ import UIKit entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical) setupFieldContainerContent(entryFieldContainer) - titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4) + titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: Padding.One) titleContainerDistance?.isActive = true entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) entryFieldContainerLeading?.isActive = true @@ -202,7 +202,7 @@ import UIKit addSubview(feedbackLabel) - feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: PaddingOne) + feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: Padding.Two) feedbackContainerDistance?.isActive = true feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) feedbackLabelLeading?.isActive = true @@ -240,9 +240,9 @@ import UIKit backgroundColor = .clear isAccessibilityElement = false - titleLabel.font = MFStyler.fontRegularMicro() + titleLabel.font = Styler.Font.RegularMicro.getFont() titleLabel.textColor = .mvmBlack - feedbackLabel.font = MFStyler.fontRegularMicro() + feedbackLabel.font = Styler.Font.RegularMicro.getFont() feedbackLabel.textColor = .mvmBlack entryFieldContainer.reset() } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index de0d1789..1b3ed015 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -28,7 +28,7 @@ import UIKit let textField = TextField() textField.isAccessibilityElement = true textField.setContentCompressionResistancePriority(.required, for: .vertical) - textField.font = MFStyler.fontRegularBodyLarge() + textField.font = Styler.Font.RegularBodyLarge.getFont() textField.textColor = .mvmBlack textField.smartQuotesType = .no textField.smartDashesType = .no @@ -36,6 +36,12 @@ import UIKit return textField }() + public var accessoryView: View? { + didSet { + accessoryView == nil ? removeAccessoryView() : constrainAccessoryView() + } + } + //-------------------------------------------------- // MARK: - Stored Properties //-------------------------------------------------- @@ -54,7 +60,7 @@ import UIKit public var textEntryFieldModel: TextEntryFieldModel? { return model as? TextEntryFieldModel } - + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -141,6 +147,26 @@ import UIKit //-------------------------------------------------- public var textFieldTrailingConstraint: NSLayoutConstraint? + public var accessoryViewTrailingConstraint: NSLayoutConstraint? + + public func constrainAccessoryView() { + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = accessoryView?.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint?.isActive = true + + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView!.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint?.isActive = true + accessoryView?.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + } + + public func removeAccessoryView() { + + accessoryView?.removeFromSuperview() + + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint?.isActive = true + } //-------------------------------------------------- // MARK: - Initializers @@ -169,17 +195,17 @@ import UIKit @objc open override func setupFieldContainerContent(_ container: UIView) { - textField.font = MFStyler.fontRegularBodyLarge() + textField.font = Styler.Font.RegularBodyLarge.getFont() container.addSubview(textField) NSLayoutConstraint.activate([ - textField.heightAnchor.constraint(equalToConstant: 24), - textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12), - textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16), - container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12) + textField.heightAnchor.constraint(equalToConstant: Padding.Five), + textField.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three), + textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Four), + container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: Padding.Three) ]) - textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16) + textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) textFieldTrailingConstraint?.isActive = true textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin) @@ -194,20 +220,20 @@ import UIKit @objc open override func updateView(_ size: CGFloat) { super.updateView(size) - textField.font = MFStyler.fontRegularBodyLarge() + textField.font = Styler.Font.RegularBodyLarge.getFont() layoutIfNeeded() } open override func reset() { super.reset() - textField.font = MFStyler.fontRegularBodyLarge() + textField.font = Styler.Font.RegularBodyLarge.getFont() } @objc deinit { setBothTextDelegates(to: nil) } - + @objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) { observingTextFieldDelegate = delegate uiTextFieldDelegate = delegate @@ -240,11 +266,11 @@ import UIKit text = textField.text _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) } - + @objc public func updateValidation(_ isValid: Bool) { let previousValidity = self.isValid self.isValid = isValid - + if previousValidity && !isValid { showError = true observingTextFieldDelegate?.isInvalid?(textfield: self) @@ -288,7 +314,7 @@ import UIKit super.set(with: model, delegateObject, additionalData) guard let model = model as? TextEntryFieldModel else { return } - + model.updateUI = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { if self?.isSelected ?? false { @@ -306,10 +332,13 @@ import UIKit switch model.type { case .password: textField.isSecureTextEntry = true + case .number: textField.keyboardType = .numberPad + case .email: textField.keyboardType = .emailAddress + default: break } diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift new file mode 100644 index 00000000..6686f164 --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -0,0 +1,36 @@ +// +// UIToolbar+Extension.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 4/10/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +/* +public extension UIToolbar { + + class func makeEmptyToolbar() -> UIToolbar { + + let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44.0)) + toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth] + toolbar.barStyle = .default + toolbar.barTintColor = .mvmCoolGray3 + toolbar.isTranslucent = true + + return toolbar + } + + class func getToolbarWithDoneButton(delegate: ObservingTextFieldDelegate) -> UIToolbar { + + let toolbar = makeEmptyToolbar() + let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput)) + button.tintColor = .mvmBlack + toolbar.setItems([space, button], animated: false) + + return toolbar + } +} +*/ From 98e4f3d6211d372a9602a2ceb34c7954bd6b8f2a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 13 Apr 2020 14:25:52 -0400 Subject: [PATCH 02/51] latest state of updates --- .../TextFields/DateDropdownEntryField.swift | 4 +- .../DateDropdownEntryFieldModel.swift | 5 +- .../Atoms/TextFields/DigitEntryField.swift | 9 -- .../TextFields/DigitEntryFieldModel.swift | 10 ++- .../Atomic/Atoms/TextFields/EntryField.swift | 14 ++- .../Atoms/TextFields/EntryFieldModel.swift | 85 ++++++++++--------- .../ItemDropdownEntryFieldModel.swift | 10 ++- .../Atoms/TextFields/MdnEntryField.swift | 10 +-- .../Atoms/TextFields/TextEntryField.swift | 44 +++------- .../TextFields/TextEntryFieldModel.swift | 7 +- .../Views/EntryFieldContainer.swift | 4 +- 11 files changed, 92 insertions(+), 110 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift index a7a483fc..50cca777 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift @@ -32,9 +32,7 @@ import UIKit }() public var dateFormat: String = "MMM d, y" { - didSet { - dateFormatter.dateFormat = dateFormat - } + didSet { dateFormatter.dateFormat = dateFormat } } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift index cdafc9e9..726eab1f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift @@ -33,7 +33,10 @@ required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) ?? "MMM d, y" + + if let dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) { + self.dateFormat = dateFormat + } } public override func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 38adee03..9d2c02cb 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -246,15 +246,6 @@ import UIKit } } - @objc public override func defaultValidationBlock() { - - validationBlock = { enteredValue in - guard let enteredValue = enteredValue else { return false } - - return enteredValue.count > 0 && enteredValue.count == self.digitBoxes.count - } - } - @objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) { var selectPreviousField = false diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift index 0291066c..423c1d7d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift @@ -36,8 +36,14 @@ required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) ?? 4 - secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) ?? false + + if let digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) { + self.digits = digits + } + + if let secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) { + self.secureEntry = secureEntry + } } public override func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 2487d619..8eb94f4e 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -20,7 +20,7 @@ import UIKit public private(set) var titleLabel: Label = { let label = Label() - label.font = MFStyler.fontRegularMicro() + label.font = Styler.Font.RegularMicro.getFont() label.textColor = .mvmBlack label.setContentCompressionResistancePriority(.required, for: .vertical) return label @@ -31,7 +31,7 @@ import UIKit /// Provides contextual information on the TextField. public private(set) var feedbackLabel: Label = { let label = Label() - label.font = MFStyler.fontRegularMicro() + label.font = Styler.Font.RegularMicro.getFont() label.textColor = .mvmBlack label.setContentCompressionResistancePriority(.required, for: .vertical) return label @@ -174,8 +174,6 @@ import UIKit @objc final public override func setupView() { super.setupView() - guard subviews.isEmpty else { return } - isAccessibilityElement = false setContentCompressionResistancePriority(.required, for: .vertical) accessibilityElements = [titleLabel, feedbackLabel] @@ -258,13 +256,13 @@ import UIKit title = model.title feedback = model.feedback errorMessage = model.errorMessage - isEnabled = model.isEnabled + isEnabled = model.enabled - if let isLocked = model.isLocked { + if let isLocked = model.locked { self.isLocked = isLocked - } else if let isSelected = model.isSelected{ - self.isSelected = isSelected + } else if let selected = model.selected { + self.isSelected = selected } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 729b3516..efd47e1d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -9,8 +9,8 @@ import Foundation -@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol { - +@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -20,31 +20,24 @@ import Foundation } public var backgroundColor: Color? - public var title: String? + public var title: String = "" public var feedback: String? public var errorMessage: String = "" - public var isEnabled: Bool = true - public var isLocked: Bool? - public var isSelected: Bool? + public var enabled: Bool = true + public var locked: Bool? + public var selected: Bool? public var text: String? - public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? - + public var isValid: Bool? { - didSet { - updateUI?() - } + didSet { updateUI?() } } /// Temporary binding mechanism for the view to update on enable changes. - public var updateUI: (() -> Void)? + public var updateUI: (() -> ())? - public func setValidity(_ valid: Bool, rule: RulesProtocol) { - self.isValid = valid - } - //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -52,23 +45,29 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor - case title = "label" - case isEnabled + case title + case enabled case feedback - case errorMessage = "errorMsg" - case isLocked - case isSelected - case isValid - case isRequired = "required" + case errorMessage + case locked + case selected case text case fieldKey case groupName } - + + //-------------------------------------------------- + // MARK: - Validation Methods + //-------------------------------------------------- + public func formFieldValue() -> AnyHashable? { return text } + public func setValidity(_ valid: Bool, rule: RulesProtocol) { + self.isValid = valid + } + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -81,20 +80,26 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - title = try typeContainer.decodeIfPresent(String.self, forKey: .title) - feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) - errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? "" - isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true - isLocked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isLocked) - isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected) - isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid) - text = try typeContainer.decodeIfPresent(String.self, forKey: .text) + if let title = try typeContainer.decodeIfPresent(String.self, forKey: .title) { + self.title = title + } + + feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) + + if let errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) { + self.errorMessage = errorMessage + } + + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } + + locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked) + selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) + text = try typeContainer.decodeIfPresent(String.self, forKey: .text) baseValue = text fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { - self.groupName = groupName - } } public func encode(to encoder: Encoder) throws { @@ -103,13 +108,11 @@ import Foundation try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(title, forKey: .title) try container.encodeIfPresent(feedback, forKey: .feedback) - try container.encode(errorMessage, forKey: .errorMessage) - try container.encode(isEnabled, forKey: .isEnabled) - try container.encode(isLocked, forKey: .isLocked) - try container.encode(isSelected, forKey: .isSelected) - try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(isValid, forKey: .isValid) try container.encodeIfPresent(text, forKey: .text) try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encodeIfPresent(locked, forKey: .locked) + try container.encodeIfPresent(selected, forKey: .selected) + try container.encode(errorMessage, forKey: .errorMessage) + try container.encode(enabled, forKey: .enabled) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 56612b7b..2f2003c0 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -35,8 +35,14 @@ required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - options = try typeContainer.decode([String].self, forKey: .options) - selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0 + + if let options = try typeContainer.decodeIfPresent([String].self, forKey: .options) { + self.options = options + } + + if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) { + self.selectedIndex = selectedIndex + } } public override func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 77b5a4a4..4f9f5d8c 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -107,18 +107,18 @@ import MVMCore isValid = true return true } - + let isValid = hasValidMDN() - + if isValid { showError = false - + } else { errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") showError = true UIAccessibility.post(notification: .layoutChanged, argument: textField) } - + return isValid } @@ -196,7 +196,7 @@ import MVMCore } @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { - + return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 1b3ed015..9d78416d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -37,9 +37,7 @@ import UIKit }() public var accessoryView: View? { - didSet { - accessoryView == nil ? removeAccessoryView() : constrainAccessoryView() - } + didSet { accessoryView == nil ? removeAccessoryView() : constrainAccessoryView() } } //-------------------------------------------------- @@ -108,12 +106,6 @@ import UIKit set { textField.placeholder = newValue } } - //-------------------------------------------------- - // MARK: - Property Observers - //-------------------------------------------------- - - public var validationBlock: ((_ value: String?) -> Bool)? - //-------------------------------------------------- // MARK: - Delegate Properties //-------------------------------------------------- @@ -155,9 +147,11 @@ import UIKit textFieldTrailingConstraint = accessoryView?.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) textFieldTrailingConstraint?.isActive = true - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView!.trailingAnchor, constant: Padding.Four) - accessoryViewTrailingConstraint?.isActive = true - accessoryView?.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + if let accessoryView = accessoryView { + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint?.isActive = true + accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + } } public func removeAccessoryView() { @@ -242,15 +236,7 @@ import UIKit //-------------------------------------------------- // MARK: - Observing for Change (TextFieldDelegate) //-------------------------------------------------- - - public func defaultValidationBlock() { - - validationBlock = { enteredValue in - guard let enteredValue = enteredValue else { return false } - return enteredValue.count > 0 - } - } - + @discardableResult @objc override open func resignFirstResponder() -> Bool { if validateWhenDoneEditing { @@ -317,11 +303,14 @@ import UIKit model.updateUI = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { - if self?.isSelected ?? false { - self?.updateValidation(model.isValid ?? true) + guard let self = self else { return } + + if self.isSelected { + self.updateValidation(model.isValid ?? true) } }) } + self.delegateObject = delegateObject FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) textColor.enabled = model.enabledTextColor?.uiColor @@ -343,15 +332,6 @@ import UIKit break } - if let regex = model.regex, !regex.isEmpty { - validationBlock = { enteredValue in - guard let value = enteredValue else { return false } - return MVMCoreUIUtility.validate(value, withRegularExpression: regex) - } - } else { - defaultValidationBlock() - } - uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index c35d812e..99a5dba4 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -8,6 +8,9 @@ @objcMembers public class TextEntryFieldModel: EntryFieldModel { + //-------------------------------------------------- + // MARK: - Types + //-------------------------------------------------- public enum EntryType: String, Codable { case password @@ -27,7 +30,6 @@ public var enabledTextColor: Color? public var disabledTextColor: Color? public var type: EntryType? - public var regex: String? //-------------------------------------------------- // MARK: - Keys @@ -40,7 +42,6 @@ case enabledTextColor case disabledTextColor case type - case regex } //-------------------------------------------------- @@ -55,7 +56,6 @@ enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type) - regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex) } public override func encode(to encoder: Encoder) throws { @@ -67,6 +67,5 @@ try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor) try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor) try container.encodeIfPresent(type, forKey: .type) - try container.encodeIfPresent(regex, forKey: .regex) } } diff --git a/MVMCoreUI/Containers/Views/EntryFieldContainer.swift b/MVMCoreUI/Containers/Views/EntryFieldContainer.swift index 3a8fac64..9ccd1d25 100644 --- a/MVMCoreUI/Containers/Views/EntryFieldContainer.swift +++ b/MVMCoreUI/Containers/Views/EntryFieldContainer.swift @@ -25,9 +25,7 @@ import UIKit /// Total control over the drawn top, bottom, left and right borders. public var disableAllBorders = false { - didSet { - bottomBar?.isHidden = disableAllBorders - } + didSet { bottomBar?.isHidden = disableAllBorders } } private(set) var fieldState: FieldState = .original { From 1f8cf7c4d03fa439f48e4dfac496bcd162849bbf Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 13 Apr 2020 16:28:02 -0400 Subject: [PATCH 03/51] EntryField updates --- .../TextFields/BaseDropdownEntryField.swift | 8 ++++- .../Atoms/TextFields/DigitEntryField.swift | 10 ++++++ .../Atomic/Atoms/TextFields/EntryField.swift | 16 ++++----- .../Atoms/TextFields/EntryFieldModel.swift | 4 ++- .../Atoms/TextFields/MdnEntryField.swift | 24 +++++++++++++- .../Atoms/TextFields/TextEntryField.swift | 31 +++--------------- .../alert_standard.imageset/Contents.json | 23 +++++++++++++ .../alert_standard @1x.png | Bin 0 -> 279 bytes .../alert_standard @2x.png | Bin 0 -> 525 bytes .../alert_standard @3x.png | Bin 0 -> 771 bytes 10 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift index bf1dbfab..f7083df5 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift @@ -64,7 +64,13 @@ import UIKit super.setupFieldContainerContent(container) container.addSubview(dropDownCaretView) - accessoryView = dropDownCaretView + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6) + textFieldTrailingConstraint?.isActive = true + + container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true + dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 9d2c02cb..25900f27 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -76,6 +76,15 @@ import UIKit public var digitBoxes: [DigitBox] = [] private var selectedDigitBox: DigitBox? + public lazy var errorImage: UIImageView = { + let image = MVMCoreUIUtility.imageNamed("alert_standard") + let imageView = UIImageView(image: image) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true + imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true + return imageView + }() + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -205,6 +214,7 @@ import UIKit isAccessibilityElement = false entryFieldContainer.disableAllBorders = true + usesAccessoryView = false } @objc private func createDigitField() -> DigitBox { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 8eb94f4e..23225a57 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -48,14 +48,6 @@ import UIKit //-------------------------------------------------- public var isValid: Bool = false - public var errorMessage: String? - public var standardMessage: String? { - didSet { - if !showError { - feedback = standardMessage - } - } - } //-------------------------------------------------- // MARK: - Computed Properties @@ -75,7 +67,7 @@ import UIKit public var showError: Bool { get { return entryFieldContainer.showError } set (error) { - self.feedback = error ? self.errorMessage : self.standardMessage + self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.informativeMessage self.entryFieldContainer.showError = error } } @@ -121,6 +113,10 @@ import UIKit } } + public var entryFieldModel: EntryFieldModel? { + return model as? EntryFieldModel + } + //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- @@ -242,6 +238,7 @@ import UIKit titleLabel.textColor = .mvmBlack feedbackLabel.font = Styler.Font.RegularMicro.getFont() feedbackLabel.textColor = .mvmBlack + feedbackLabel.text = nil entryFieldContainer.reset() } @@ -255,7 +252,6 @@ import UIKit title = model.title feedback = model.feedback - errorMessage = model.errorMessage isEnabled = model.enabled if let isLocked = model.locked { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index efd47e1d..1f0e3d78 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -22,7 +22,8 @@ import Foundation public var backgroundColor: Color? public var title: String = "" public var feedback: String? - public var errorMessage: String = "" + public var errorMessage: String? + public var informativeMessage: String? public var enabled: Bool = true public var locked: Bool? public var selected: Bool? @@ -86,6 +87,7 @@ import Foundation } feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) + informativeMessage = feedback if let errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) { self.errorMessage = errorMessage diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 4f9f5d8c..dfca1b76 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -86,6 +86,28 @@ import MVMCore textField.inputAccessoryView = toolbar } + public func constrainAccessoryView() { + + guard let accessoryView = accessoryView else { return } + + entryFieldContainer.addSubview(accessoryView) + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = accessoryView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint?.isActive = true + + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint?.isActive = true + accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + } + + public func unconstrainAccessoryView() { + + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint?.isActive = true + } + + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- @@ -114,7 +136,7 @@ import MVMCore showError = false } else { - errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") + entryFieldModel?.errorMessage = entryFieldModel?.errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") showError = true UIAccessibility.post(notification: .layoutChanged, argument: textField) } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 9d78416d..c013a246 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -35,11 +35,7 @@ import UIKit textField.smartInsertDeleteType = .no return textField }() - - public var accessoryView: View? { - didSet { accessoryView == nil ? removeAccessoryView() : constrainAccessoryView() } - } - + //-------------------------------------------------- // MARK: - Stored Properties //-------------------------------------------------- @@ -52,6 +48,8 @@ import UIKit /// Validate on each entry in the textField. Default: true public var validateEachCharacter: Bool = true + var usesAccessoryView: Bool = true + /// Validate when user resigns editing. Default: true public var validateWhenDoneEditing: Bool = true @@ -82,7 +80,7 @@ import UIKit set (error) { if error { - textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", errorMessage ?? "") + textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", entryFieldModel?.errorMessage ?? "") } else { textField.accessibilityValue = nil } @@ -141,27 +139,6 @@ import UIKit public var textFieldTrailingConstraint: NSLayoutConstraint? public var accessoryViewTrailingConstraint: NSLayoutConstraint? - public func constrainAccessoryView() { - - textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = accessoryView?.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) - textFieldTrailingConstraint?.isActive = true - - if let accessoryView = accessoryView { - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) - accessoryViewTrailingConstraint?.isActive = true - accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true - } - } - - public func removeAccessoryView() { - - accessoryView?.removeFromSuperview() - - textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) - textFieldTrailingConstraint?.isActive = true - } - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json new file mode 100644 index 00000000..af2434ac --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "alert_standard @1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "alert_standard @2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "alert_standard @3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fbe367cf64f711290e7b32a70ec1a601d97264 GIT binary patch literal 279 zcmV+y0qFjTP)Px#(Md!>R5%f(mB9_dFbqX2!InL6<;Da|!I>?X09Igy9=Zbu{Hj<=Lu@DEOJB9( zpQlE#+G&b4OJqr={!3@s{SjZ2saYG6!cN(4>LF+irrd6*2kVAfu$PcPsTTt!uY=-G3584g$pu?~d%FyDWZ=u5U d$(%O-0>1XbOgi*8)%^ef002ovPDHLkV1iTmbsPWy literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d40e714930cf2c5fd9e0c850db453c7bac83e141 GIT binary patch literal 525 zcmV+o0`mQdP)Px$$4Nv%R9Fek+09MFKn#ZA2<~*jl^*zOfHOxrfEJ((&Tya^ieNe;+B(eNXdYS#wm^oZIWwMv9xU{teq>cs#%_p%nZ zvYCk!+gL#AOkknc?jX~pv+aBFx~z-Ev9i`FKD6C`w@Dq1Kc~3XMFNN;mpOX97YU7P z+-B(W+9tI(N?h;nm>S3KIwZdz%O*z0Az3{~KZt5rsAh*WAT; P00000NkvXXu0mjfMds}x literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png new file mode 100644 index 0000000000000000000000000000000000000000..00589541efe77d734e8d84564871b848afbed248 GIT binary patch literal 771 zcmV+e1N{7nP)Px%y-7qtRA>d=+c8fRK@K*a}^5-I1zeRH2 zTE#9jpONE4avzUbi`awW7jg<~<2;7Pb{z!#MjDFSYviXzviAGBMiZMpv)?iH3~9ld zW8I^tu#ZjZwjApkJqK&$@=Fl~;&7f;ySB@^l zzJOp%l4CcC>Tga;u|$=C`Tf<<3akQL1+BuWz@ca*RtXM4tFdaZ6di$$087wO*eGxj zIugr;Jx7j7a!e7kPg&7eqIQrem}9EAG5QHQrdJnvorx1D;{hg1!5mY@6q?4raR*;N zBK<-luxxfW>BF8JQ%4R>Bdx<5WDP8PF@7MeAM2>dp=lkCk+uL{828tWxnCVun9%yM zjtpA-#r_jE`+~Fu@Qy%qoTGvDV;vndS--Ehqq}A1|K`Sg?S|t@f-l|l4^c<|N_(WQ z-7;h)Esxx6mjs`=fm^7Lkm}QsYcY7Ful+HKng&{Yobo}<(-Ql=LfYRH>xjs`LjOB0 zu^~^&xjTIk&-6?5GB9g(tqWCi&i)&D_ed)?bNMfy1zBv;rKC zRiaD5)vzjb3Aj2|g|>O-Y*&W0MJiv&Y|g3e%CWYv8t7)QHPFprBhk%bBhbxbmFRA; z3Uqha5_GrNWzgMY4ZV*dca6+n_h#Mof5RKrw)-ej^fkuT@AD Date: Mon, 13 Apr 2020 16:42:39 -0400 Subject: [PATCH 04/51] revising error view to only MDN --- .../TextFields/BaseDropdownEntryField.swift | 2 +- .../Atoms/TextFields/MdnEntryField.swift | 29 ++++++++++++++----- .../Atoms/TextFields/TextEntryField.swift | 1 - 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift index f7083df5..ee697a3e 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift @@ -69,7 +69,7 @@ import UIKit textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6) textFieldTrailingConstraint?.isActive = true - container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true + container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: Padding.Four).isActive = true dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index dfca1b76..c973071d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -22,6 +22,8 @@ import MVMCore public var isNationalMDN = true public var shouldValidateMDN = false + public var accessoryViewTrailingConstraint: NSLayoutConstraint? + //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- @@ -38,6 +40,15 @@ import MVMCore } } + public lazy var errorImage: UIImageView = { + let image = MVMCoreUIUtility.imageNamed("alert_standard") + let imageView = UIImageView(image: image) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true + imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true + return imageView + }() + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -84,21 +95,26 @@ import MVMCore let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:))) toolbar.items = [contacts, space, dismissButton] textField.inputAccessoryView = toolbar + +// textFieldTrailingConstraint?.isActive = false +// textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) +// textFieldTrailingConstraint?.isActive = true +// +// container.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true +// errorImage.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true } public func constrainAccessoryView() { - guard let accessoryView = accessoryView else { return } - - entryFieldContainer.addSubview(accessoryView) + entryFieldContainer.addSubview(errorImage) textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = accessoryView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) textFieldTrailingConstraint?.isActive = true - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four) accessoryViewTrailingConstraint?.isActive = true - accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true } public func unconstrainAccessoryView() { @@ -107,7 +123,6 @@ import MVMCore textFieldTrailingConstraint?.isActive = true } - //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index c013a246..1c5563aa 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -137,7 +137,6 @@ import UIKit //-------------------------------------------------- public var textFieldTrailingConstraint: NSLayoutConstraint? - public var accessoryViewTrailingConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Initializers From cc5eb5c58e79d1a2a911026bb455c7a859bd0139 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 13 Apr 2020 16:44:39 -0400 Subject: [PATCH 05/51] puling over code to be worked on later --- .../Atoms/TextFields/MdnEntryField.swift | 37 ---------------- .../Atoms/TextFields/TextEntryField.swift | 43 +++++++++++++++++++ 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index c973071d..71bc0539 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -22,8 +22,6 @@ import MVMCore public var isNationalMDN = true public var shouldValidateMDN = false - public var accessoryViewTrailingConstraint: NSLayoutConstraint? - //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- @@ -40,15 +38,6 @@ import MVMCore } } - public lazy var errorImage: UIImageView = { - let image = MVMCoreUIUtility.imageNamed("alert_standard") - let imageView = UIImageView(image: image) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true - imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true - return imageView - }() - //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -95,32 +84,6 @@ import MVMCore let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:))) toolbar.items = [contacts, space, dismissButton] textField.inputAccessoryView = toolbar - -// textFieldTrailingConstraint?.isActive = false -// textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) -// textFieldTrailingConstraint?.isActive = true -// -// container.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true -// errorImage.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true - } - - public func constrainAccessoryView() { - - entryFieldContainer.addSubview(errorImage) - - textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) - textFieldTrailingConstraint?.isActive = true - - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four) - accessoryViewTrailingConstraint?.isActive = true - errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true - } - - public func unconstrainAccessoryView() { - - textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) - textFieldTrailingConstraint?.isActive = true } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 1c5563aa..98c03238 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -337,3 +337,46 @@ extension TextEntryField { textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" } } + +// FOR isSecureEntry state +/* + + public var accessoryViewTrailingConstraint: NSLayoutConstraint? + + + // textFieldTrailingConstraint?.isActive = false + // textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + // textFieldTrailingConstraint?.isActive = true + // + // container.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true + // errorImage.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true + + + public lazy var errorImage: UIImageView = { + let image = MVMCoreUIUtility.imageNamed("alert_standard") + let imageView = UIImageView(image: image) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true + imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true + return imageView + }() + + public func constrainAccessoryView() { + + entryFieldContainer.addSubview(errorImage) + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint?.isActive = true + + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint?.isActive = true + errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + } + + public func unconstrainAccessoryView() { + + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint?.isActive = true + } + */ From 949cd3292fb61f3d5421b94b72302ad519d6120c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 13 Apr 2020 17:07:28 -0400 Subject: [PATCH 06/51] resolving state of error image --- .../Atoms/TextFields/DigitEntryField.swift | 10 -- .../Atoms/TextFields/TextEntryField.swift | 102 ++++++++++-------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 25900f27..9d2c02cb 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -76,15 +76,6 @@ import UIKit public var digitBoxes: [DigitBox] = [] private var selectedDigitBox: DigitBox? - public lazy var errorImage: UIImageView = { - let image = MVMCoreUIUtility.imageNamed("alert_standard") - let imageView = UIImageView(image: image) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true - imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true - return imageView - }() - //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -214,7 +205,6 @@ import UIKit isAccessibilityElement = false entryFieldContainer.disableAllBorders = true - usesAccessoryView = false } @objc private func createDigitField() -> DigitBox { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 98c03238..b267cd32 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -35,7 +35,22 @@ import UIKit textField.smartInsertDeleteType = .no return textField }() - + + private var standardAccessoryView: UIView? + + public var accessoryView: UIView? { + didSet { accessoryView == nil ? unconstrainAccessoryView() : constrainAccessoryView() } + } + + public lazy var errorImage: UIImageView = { + let image = MVMCoreUIUtility.imageNamed("alert_standard") + let imageView = UIImageView(image: image) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true + imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true + return imageView + }() + //-------------------------------------------------- // MARK: - Stored Properties //-------------------------------------------------- @@ -85,6 +100,17 @@ import UIKit textField.accessibilityValue = nil } + if textField.isSecureTextEntry { + if !error { + accessoryView?.removeFromSuperview() + accessoryView = nil + accessoryView = standardAccessoryView + } else { + standardAccessoryView = accessoryView + accessoryView = errorImage + } + } + super.showError = error } } @@ -137,6 +163,28 @@ import UIKit //-------------------------------------------------- public var textFieldTrailingConstraint: NSLayoutConstraint? + public var accessoryViewTrailingConstraint: NSLayoutConstraint? + + public func constrainAccessoryView() { + + guard let accessoryView = accessoryView else { return } + + entryFieldContainer.addSubview(accessoryView) + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = accessoryView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint?.isActive = true + + accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) + accessoryViewTrailingConstraint?.isActive = true + accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + } + + public func unconstrainAccessoryView() { + + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint?.isActive = true + } //-------------------------------------------------- // MARK: - Initializers @@ -185,6 +233,15 @@ import UIKit entryFieldContainer.addGestureRecognizer(tap) accessibilityElements = [titleLabel, textField, feedbackLabel] + + // TODO: Remove these two lines. + let tapErr = UITapGestureRecognizer(target: self, action: #selector(tapForError)) + titleLabel.addGestureRecognizer(tapErr) + } + + // TODO: Remove this func + @objc func tapForError() { + showError.toggle() } @objc open override func updateView(_ size: CGFloat) { @@ -337,46 +394,3 @@ extension TextEntryField { textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" } } - -// FOR isSecureEntry state -/* - - public var accessoryViewTrailingConstraint: NSLayoutConstraint? - - - // textFieldTrailingConstraint?.isActive = false - // textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) - // textFieldTrailingConstraint?.isActive = true - // - // container.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true - // errorImage.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true - - - public lazy var errorImage: UIImageView = { - let image = MVMCoreUIUtility.imageNamed("alert_standard") - let imageView = UIImageView(image: image) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true - imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true - return imageView - }() - - public func constrainAccessoryView() { - - entryFieldContainer.addSubview(errorImage) - - textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) - textFieldTrailingConstraint?.isActive = true - - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four) - accessoryViewTrailingConstraint?.isActive = true - errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true - } - - public func unconstrainAccessoryView() { - - textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) - textFieldTrailingConstraint?.isActive = true - } - */ From a4ede5281034db760bdedf7c766a6d5fbdc8d090 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 09:54:27 -0400 Subject: [PATCH 07/51] improved error presentation --- MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift | 10 +++++----- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 9 --------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 23225a57..5e874936 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -211,11 +211,11 @@ import UIKit entryFieldContainer.refreshUI() } - /// Method to override. - /// Intended to add the interactive content (i.e. textField) to the entryFieldContainer. - @objc open func setupFieldContainerContent(_ container: UIView) { - // To be overridden by subclass. - } + /** + Method to override. + Intended to add the interactive content (i.e. textField) to the entryFieldContainer. + */ + @objc open func setupFieldContainerContent(_ container: UIView) { } @objc open override func updateView(_ size: CGFloat) { super.updateView(size) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index b267cd32..e9ba7d27 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -233,15 +233,6 @@ import UIKit entryFieldContainer.addGestureRecognizer(tap) accessibilityElements = [titleLabel, textField, feedbackLabel] - - // TODO: Remove these two lines. - let tapErr = UITapGestureRecognizer(target: self, action: #selector(tapForError)) - titleLabel.addGestureRecognizer(tapErr) - } - - // TODO: Remove this func - @objc func tapForError() { - showError.toggle() } @objc open override func updateView(_ size: CGFloat) { From e03a4abbd5eb29a68a727361b3cae95a16c67eb2 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 10:29:49 -0400 Subject: [PATCH 08/51] broadening scope of toolbar func. improving MDN entryfield selection behavior. --- .../Atoms/TextFields/DateDropdownEntryField.swift | 2 +- .../Atomic/Atoms/TextFields/DigitEntryField.swift | 4 ++-- .../Atomic/Atoms/TextFields/MdnEntryField.swift | 14 +++++++++++++- .../Atomic/Atoms/TextFields/TextEntryField.swift | 9 +++++---- .../Atomic/Extensions/UIToolbar+Extension.swift | 8 ++++---- .../BaseControllers/ScrollingViewController.swift | 2 +- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- .../MVMCoreUICommonViewsUtility+Extension.swift | 2 +- 8 files changed, 28 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift index 50cca777..f16720f0 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift @@ -102,7 +102,7 @@ import UIKit } } - @objc override func dismissFieldInput(_ sender: Any?) { + @objc public override func dismissFieldInput(_ sender: Any?) { setTextWith(date: datePicker?.date) super.dismissFieldInput(sender) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 9d2c02cb..bc361abe 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -211,7 +211,7 @@ import UIKit let digitBox = DigitBox() digitBox.isAccessibilityElement = true - digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: self) + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: self, action: #selector(dismissFieldInput)) digitBox.digitField.delegate = self digitBox.digitBoxDelegate = self return digitBox @@ -313,7 +313,7 @@ import UIKit return true } - @objc override func dismissFieldInput(_ sender: Any?) { + @objc public override func dismissFieldInput(_ sender: Any?) { digitBoxes.forEach { if $0.isSelected { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 71bc0539..620ce26f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -48,6 +48,18 @@ import MVMCore set { text = MVMCoreUIUtility.formatMdn(newValue) } } + /// Toggles selected or original (unselected) UI. + public override var isSelected: Bool { + get { return entryFieldContainer.isSelected } + set (selected) { + if selected && showError { + showError = false + } + + super.isSelected = selected + } + } + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -81,7 +93,7 @@ import MVMCore let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:))) - let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:))) + let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput)) toolbar.items = [contacts, space, dismissButton] textField.inputAccessoryView = toolbar } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index e9ba7d27..f138d860 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -15,7 +15,7 @@ import UIKit /// Called when the entered text becomes invalid based on the validation block @objc optional func isInvalid(textfield: TextEntryField?) /// Dismisses the keyboard. - @objc optional func dismissFieldInput(sender: Any?) + @objc optional func dismissFieldInput(_ sender: Any?) } @@ -227,7 +227,7 @@ import UIKit textFieldTrailingConstraint?.isActive = true textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin) - textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd) + textField.addTarget(self, action: #selector(dismissFieldInput), for: .editingDidEnd) let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing)) entryFieldContainer.addGestureRecognizer(tap) @@ -312,7 +312,7 @@ import UIKit } } - @objc func dismissFieldInput(_ sender: Any?) { + @objc public func dismissFieldInput(_ sender: Any?) { resignFirstResponder() } @@ -358,7 +358,8 @@ import UIKit uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate - textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self) + textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, + action: #selector(observingTextFieldDelegate?.dismissFieldInput)) } } diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index 6686f164..4d31f708 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -8,7 +8,7 @@ import Foundation -/* + public extension UIToolbar { class func makeEmptyToolbar() -> UIToolbar { @@ -22,15 +22,15 @@ public extension UIToolbar { return toolbar } - class func getToolbarWithDoneButton(delegate: ObservingTextFieldDelegate) -> UIToolbar { + class func getToolbarWithDoneButton(delegate: Any?, action: Selector) -> UIToolbar { let toolbar = makeEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput)) + let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) button.tintColor = .mvmBlack toolbar.setItems([space, button], animated: false) return toolbar } } -*/ + diff --git a/MVMCoreUI/BaseControllers/ScrollingViewController.swift b/MVMCoreUI/BaseControllers/ScrollingViewController.swift index 2e4eceef..97e83f98 100644 --- a/MVMCoreUI/BaseControllers/ScrollingViewController.swift +++ b/MVMCoreUI/BaseControllers/ScrollingViewController.swift @@ -36,7 +36,7 @@ open class ScrollingViewController: ViewController { super.viewDidLoad() // Adds the tap gesture to dismiss the keyboard. - dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput(sender:))) + dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput)) view.addGestureRecognizer(dismissKeyboardTapGesture!) dismissKeyboardTapGesture?.isEnabled = false scrollView.alwaysBounceVertical = false diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index eb4be908..c74b6a0c 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -399,7 +399,7 @@ import UIKit } } - @objc open func dismissFieldInput(sender: Any?) { + @objc open func dismissFieldInput(_ sender: Any?) { selectedField?.resignFirstResponder() } diff --git a/MVMCoreUI/Utility/MVMCoreUICommonViewsUtility+Extension.swift b/MVMCoreUI/Utility/MVMCoreUICommonViewsUtility+Extension.swift index 3ee452b0..704cf801 100644 --- a/MVMCoreUI/Utility/MVMCoreUICommonViewsUtility+Extension.swift +++ b/MVMCoreUI/Utility/MVMCoreUICommonViewsUtility+Extension.swift @@ -14,7 +14,7 @@ public extension MVMCoreUICommonViewsUtility { let toolbar = self.makeEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput(sender:))) + let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput)) button.tintColor = .black toolbar.setItems([space, button], animated: false) From 3466be23c8ad2a0f2c549c9b5baffb655220ae7e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 10:49:36 -0400 Subject: [PATCH 09/51] little changes --- MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift | 3 +-- MVMCoreUI/Styles/Styler.swift | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index 4d31f708..494aaf45 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -13,7 +13,7 @@ public extension UIToolbar { class func makeEmptyToolbar() -> UIToolbar { - let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44.0)) + let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)) toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth] toolbar.barStyle = .default toolbar.barTintColor = .mvmCoolGray3 @@ -33,4 +33,3 @@ public extension UIToolbar { return toolbar } } - diff --git a/MVMCoreUI/Styles/Styler.swift b/MVMCoreUI/Styles/Styler.swift index b5d6627c..509ad107 100644 --- a/MVMCoreUI/Styles/Styler.swift +++ b/MVMCoreUI/Styles/Styler.swift @@ -10,10 +10,8 @@ import Foundation open class Styler { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- + // MARK:- Font Enum public enum Font: String, Codable { case Title2XLarge case TitleXLarge From 5f539aa6b724173c1d27ab96d9687c25172e06f0 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 11:57:51 -0400 Subject: [PATCH 10/51] extending picker classes for more logical separation and modernization --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++ .../TextFields/DateDropdownEntryField.swift | 4 +- .../Atoms/TextFields/DigitEntryField.swift | 3 +- .../TextFields/ItemDropdownEntryField.swift | 2 +- .../Atoms/TextFields/MdnEntryField.swift | 2 +- .../Extensions/UIDatePicker+Extension.swift | 37 ++++++++++++++++++ .../Extensions/UIPickerView+Extension.swift | 39 +++++++++++++++++++ .../Extensions/UIToolbar+Extension.swift | 28 ++++++++++++- 8 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift create mode 100644 MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index cdba6c77..3803e156 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -104,6 +104,8 @@ 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; 0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; }; + 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; }; + 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; }; 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; }; 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; }; 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; @@ -532,6 +534,8 @@ 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; 0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = ""; }; 0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = ""; }; + 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = ""; }; + 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPickerView+Extension.swift"; sourceTree = ""; }; 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = ""; }; 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = ""; }; 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; @@ -1119,6 +1123,8 @@ D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */, 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */, 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */, + 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */, + 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */, ); path = Extensions; sourceTree = ""; @@ -2292,6 +2298,7 @@ 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */, + 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */, D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */, D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */, C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */, @@ -2372,6 +2379,7 @@ 8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */, D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */, 012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */, + 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, 011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift index f16720f0..1c2fef83 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift @@ -67,10 +67,10 @@ import UIKit public override func setupFieldContainerContent(_ container: UIView) { super.setupFieldContainerContent(container) - datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField) + datePicker = UIDatePicker.addDatePicker(to: textField) datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged) datePicker?.timeZone = NSTimeZone.system - MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: self) + UIToolbar.addDismissToolbar(to: textField, delegate: self, action: #selector(dismissFieldInput)) } @objc public func setDatePickerDuration(from startDate: Date?, to endDate: Date?, showStartDate: Bool = true) { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index bc361abe..2bf80e9d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -331,7 +331,8 @@ import UIKit setAsSecureTextEntry(model.secureEntry) for digitBox in digitBoxes { - digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self) + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self, + action: #selector(observingTextFieldDelegate?.dismissFieldInput)) } super.set(with: model, delegateObject, additionalData) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift index bd6d793c..4bddc5b9 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift @@ -62,7 +62,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { @objc open override func setupFieldContainerContent(_ container: UIView) { super.setupFieldContainerContent(container) - pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self) + pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput)) textField.hideBlinkingCaret = true textField.autocorrectionType = .no uiTextFieldDelegate = self diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 620ce26f..28f7ba21 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -90,7 +90,7 @@ import MVMCore textField.keyboardType = .numberPad - let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar() + let toolbar = UIToolbar.emptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:))) let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput)) diff --git a/MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift new file mode 100644 index 00000000..4c1acfcb --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift @@ -0,0 +1,37 @@ +// +// UIDatePicker+Extension.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 4/14/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public extension UIDatePicker { + + class func addDatePicker(to textField: UITextField) -> UIDatePicker { + + let datePicker = UIDatePicker() + datePicker.backgroundColor = .mvmWhite + datePicker.datePickerMode = .date + + let locale = NSLocale.current as NSLocale + datePicker.locale = locale as Locale + datePicker.calendar = locale.object(forKey: .calendar) as? Calendar + textField.inputView = datePicker + + return datePicker + } + + class func addTimeAndDatePicker(to textField: UITextField) -> UIDatePicker { + + let datePicker = UIDatePicker() + datePicker.backgroundColor = .mvmWhite + datePicker.datePickerMode = .time + textField.inputView = datePicker + + return datePicker + } +} diff --git a/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift new file mode 100644 index 00000000..795583bb --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift @@ -0,0 +1,39 @@ +// +// UIPickerView.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 4/14/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + + +public extension UIPickerView { + + class func createPickerView() -> UIPickerView { + + let picker = UIPickerView(frame: .zero) + picker.backgroundColor = .mvmWhite + picker.showsSelectionIndicator = true + return picker + } + + class func addPicker(to textField: UITextField, delegate: (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)?, dismissAction: Selector?) -> UIPickerView { + + // Sets up the picker (same tag as the textfield) + let picker = createPickerView() + picker.delegate = delegate + picker.dataSource = delegate + picker.tag = textField.tag + textField.inputView = picker + + // Adds a dismiss toolbar, since all fields with pickers should have one. + if let dismissAction = dismissAction { + UIToolbar.addDismissToolbar(to: textField, delegate: delegate, action: dismissAction) + } + + return picker + } +} diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index 494aaf45..1a677469 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -8,10 +8,15 @@ import Foundation +public protocol TextFieldOrView { } + +extension UITextView: TextFieldOrView { } +extension UITextField: TextFieldOrView { } + public extension UIToolbar { - class func makeEmptyToolbar() -> UIToolbar { + class func emptyToolbar() -> UIToolbar { let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)) toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth] @@ -24,7 +29,7 @@ public extension UIToolbar { class func getToolbarWithDoneButton(delegate: Any?, action: Selector) -> UIToolbar { - let toolbar = makeEmptyToolbar() + let toolbar = emptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) button.tintColor = .mvmBlack @@ -32,4 +37,23 @@ public extension UIToolbar { return toolbar } + + class func addDismissToolbar(to object: TextFieldOrView?, delegate: Any?, action: Selector) { + + let toolbar = emptyToolbar() + let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) + dismissButton.tintColor = UIColor.black + toolbar.items = [space, dismissButton] + + switch object { + case is UITextField: + (object as? UITextField)?.inputAccessoryView = toolbar + + case is UITextView: + (object as? UITextView)?.inputAccessoryView = toolbar + default: + return + } + } } From ddc44a17edf4ad1e8018ba585662262951293c6f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 14:01:23 -0400 Subject: [PATCH 11/51] error image for secure entry state --- .../TextFields/ItemDropdownEntryField.swift | 2 + .../Atoms/TextFields/MdnEntryField.swift | 4 +- .../Atoms/TextFields/TextEntryField.swift | 64 ++++++------------- .../Extensions/UIPickerView+Extension.swift | 3 +- .../Extensions/UIToolbar+Extension.swift | 11 ++-- 5 files changed, 32 insertions(+), 52 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift index 4bddc5b9..cc8a4c71 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift @@ -8,6 +8,8 @@ import UIKit +public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource) + open class ItemDropdownEntryField: BaseDropdownEntryField { //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 28f7ba21..55a903d0 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -90,9 +90,9 @@ import MVMCore textField.keyboardType = .numberPad - let toolbar = UIToolbar.emptyToolbar() + let toolbar = UIToolbar.createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:))) + let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts)) let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput)) toolbar.items = [contacts, space, dismissButton] textField.inputAccessoryView = toolbar diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index f138d860..a90ad63b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -36,12 +36,6 @@ import UIKit return textField }() - private var standardAccessoryView: UIView? - - public var accessoryView: UIView? { - didSet { accessoryView == nil ? unconstrainAccessoryView() : constrainAccessoryView() } - } - public lazy var errorImage: UIImageView = { let image = MVMCoreUIUtility.imageNamed("alert_standard") let imageView = UIImageView(image: image) @@ -63,8 +57,6 @@ import UIKit /// Validate on each entry in the textField. Default: true public var validateEachCharacter: Bool = true - var usesAccessoryView: Bool = true - /// Validate when user resigns editing. Default: true public var validateWhenDoneEditing: Bool = true @@ -101,14 +93,7 @@ import UIKit } if textField.isSecureTextEntry { - if !error { - accessoryView?.removeFromSuperview() - accessoryView = nil - accessoryView = standardAccessoryView - } else { - standardAccessoryView = accessoryView - accessoryView = errorImage - } + showErrorView(error) } super.showError = error @@ -163,28 +148,6 @@ import UIKit //-------------------------------------------------- public var textFieldTrailingConstraint: NSLayoutConstraint? - public var accessoryViewTrailingConstraint: NSLayoutConstraint? - - public func constrainAccessoryView() { - - guard let accessoryView = accessoryView else { return } - - entryFieldContainer.addSubview(accessoryView) - - textFieldTrailingConstraint?.isActive = false - textFieldTrailingConstraint = accessoryView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) - textFieldTrailingConstraint?.isActive = true - - accessoryViewTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor, constant: Padding.Four) - accessoryViewTrailingConstraint?.isActive = true - accessoryView.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true - } - - public func unconstrainAccessoryView() { - - textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) - textFieldTrailingConstraint?.isActive = true - } //-------------------------------------------------- // MARK: - Initializers @@ -248,10 +211,6 @@ import UIKit textField.font = Styler.Font.RegularBodyLarge.getFont() } - @objc deinit { - setBothTextDelegates(to: nil) - } - @objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) { observingTextFieldDelegate = delegate uiTextFieldDelegate = delegate @@ -260,7 +219,7 @@ import UIKit //-------------------------------------------------- // MARK: - Observing for Change (TextFieldDelegate) //-------------------------------------------------- - + @discardableResult @objc override open func resignFirstResponder() -> Bool { if validateWhenDoneEditing { @@ -316,6 +275,25 @@ import UIKit resignFirstResponder() } + private func showErrorView(_ show: Bool) { + + if show { + entryFieldContainer.addSubview(errorImage) + + textFieldTrailingConstraint?.isActive = false + textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) + textFieldTrailingConstraint?.isActive = true + + entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true + errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true + + } else { + errorImage.removeFromSuperview() + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint?.isActive = true + } + } + //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift index 795583bb..aa933e05 100644 --- a/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift @@ -9,7 +9,6 @@ import Foundation - public extension UIPickerView { class func createPickerView() -> UIPickerView { @@ -20,7 +19,7 @@ public extension UIPickerView { return picker } - class func addPicker(to textField: UITextField, delegate: (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)?, dismissAction: Selector?) -> UIPickerView { + class func addPicker(to textField: UITextField, delegate: TextFieldAndPickerDelegate?, dismissAction: Selector?) -> UIPickerView { // Sets up the picker (same tag as the textfield) let picker = createPickerView() diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index 1a677469..a3e315c2 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -16,7 +16,7 @@ extension UITextField: TextFieldOrView { } public extension UIToolbar { - class func emptyToolbar() -> UIToolbar { + class func createEmptyToolbar() -> UIToolbar { let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)) toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth] @@ -29,7 +29,7 @@ public extension UIToolbar { class func getToolbarWithDoneButton(delegate: Any?, action: Selector) -> UIToolbar { - let toolbar = emptyToolbar() + let toolbar = createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) button.tintColor = .mvmBlack @@ -38,12 +38,12 @@ public extension UIToolbar { return toolbar } - class func addDismissToolbar(to object: TextFieldOrView?, delegate: Any?, action: Selector) { + class func addDismissToolbar(to object: TextFieldOrView, delegate: Any?, action: Selector) { - let toolbar = emptyToolbar() + let toolbar = createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) - dismissButton.tintColor = UIColor.black + dismissButton.tintColor = .mvmBlack toolbar.items = [space, dismissButton] switch object { @@ -52,6 +52,7 @@ public extension UIToolbar { case is UITextView: (object as? UITextView)?.inputAccessoryView = toolbar + default: return } From 7f7999774e79ff4c6bfe396520ef0298f13ee377 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 14:28:57 -0400 Subject: [PATCH 12/51] revised secure entry --- MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift | 5 ++++- .../Atomic/Atoms/TextFields/DigitEntryFieldModel.swift | 7 ------- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 2 +- .../Atomic/Atoms/TextFields/TextEntryFieldModel.swift | 1 + 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 2bf80e9d..d5648342 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -328,7 +328,10 @@ import UIKit guard let model = model as? DigitEntryFieldModel else { return } numberOfDigits = model.digits - setAsSecureTextEntry(model.secureEntry) + + if let entryType = model.type { + setAsSecureTextEntry(entryType == .secure || entryType == .password) + } for digitBox in digitBoxes { digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self, diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift index 423c1d7d..e91eca77 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift @@ -17,7 +17,6 @@ } public var digits: Int = 4 - public var secureEntry: Bool = false //-------------------------------------------------- // MARK: - Keys @@ -26,7 +25,6 @@ private enum CodingKeys: String, CodingKey { case moleculeName case digits - case secureEntry } //-------------------------------------------------- @@ -40,10 +38,6 @@ if let digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) { self.digits = digits } - - if let secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) { - self.secureEntry = secureEntry - } } public override func encode(to encoder: Encoder) throws { @@ -51,6 +45,5 @@ var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(digits, forKey: .digits) - try container.encode(secureEntry, forKey: .secureEntry) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index a90ad63b..0f4960be 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -321,7 +321,7 @@ import UIKit placeholder = model.placeholder switch model.type { - case .password: + case .password, .secure: textField.isSecureTextEntry = true case .number: diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index 99a5dba4..c12b92ac 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -14,6 +14,7 @@ public enum EntryType: String, Codable { case password + case secure case number case email } From 4f3b61944c1b49b9b986a0c22ceac19eed2cc545 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 14 Apr 2020 17:08:24 -0400 Subject: [PATCH 13/51] changing delegate --- MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index d5648342..aff5ec75 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -211,7 +211,8 @@ import UIKit let digitBox = DigitBox() digitBox.isAccessibilityElement = true - digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: self, action: #selector(dismissFieldInput)) + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, + action: #selector(observingTextFieldDelegate?.dismissFieldInput)) digitBox.digitField.delegate = self digitBox.digitBoxDelegate = self return digitBox From 7fd0df1b91de59879958a49b4bafc508d6055b5e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 12:07:49 -0400 Subject: [PATCH 14/51] revised how toolbar is configured --- .../Atomic/Atoms/TextFields/MdnEntryField.swift | 3 +++ .../Atomic/Atoms/TextFields/TextEntryField.swift | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index 55a903d0..ce36a7cb 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -89,6 +89,9 @@ import MVMCore super.setupFieldContainerContent(container) textField.keyboardType = .numberPad + } + + open override func setupTextFieldToolbar() { let toolbar = UIToolbar.createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 0f4960be..695694ac 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -182,11 +182,11 @@ import UIKit NSLayoutConstraint.activate([ textField.heightAnchor.constraint(equalToConstant: Padding.Five), textField.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three), - textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Four), + textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Three), container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: Padding.Three) ]) - textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Three) textFieldTrailingConstraint?.isActive = true textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin) @@ -216,6 +216,12 @@ import UIKit uiTextFieldDelegate = delegate } + open func setupTextFieldToolbar() { + + textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, + action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + } + //-------------------------------------------------- // MARK: - Observing for Change (TextFieldDelegate) //-------------------------------------------------- @@ -336,8 +342,7 @@ import UIKit uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate - textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, - action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + setupTextFieldToolbar() } } From 1415b1bf5e2146e65a47f3ab3d0cb4bdb646a040 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 12:11:29 -0400 Subject: [PATCH 15/51] revised how toolbar is configured --- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 695694ac..2b68bb6b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -290,12 +290,12 @@ import UIKit textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) textFieldTrailingConstraint?.isActive = true - entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Four).isActive = true + entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Three).isActive = true errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true } else { errorImage.removeFromSuperview() - textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Four) + textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) textFieldTrailingConstraint?.isActive = true } } From 217ec0333e93d3e6f0b89671002bb0ca45a6fbc1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 12:14:27 -0400 Subject: [PATCH 16/51] resolving all default button tint to black --- MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index a3e315c2..49826504 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -22,6 +22,7 @@ public extension UIToolbar { toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth] toolbar.barStyle = .default toolbar.barTintColor = .mvmCoolGray3 + toolbar.tintColor = .mvmBlack toolbar.isTranslucent = true return toolbar @@ -32,7 +33,6 @@ public extension UIToolbar { let toolbar = createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) - button.tintColor = .mvmBlack toolbar.setItems([space, button], animated: false) return toolbar @@ -43,7 +43,6 @@ public extension UIToolbar { let toolbar = createEmptyToolbar() let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) - dismissButton.tintColor = .mvmBlack toolbar.items = [space, dismissButton] switch object { From 904f8a35a262f931f0dd16dc0e718d2f02770258 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 13:00:04 -0400 Subject: [PATCH 17/51] reverting change --- MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift | 1 + MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift | 2 +- MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift index 1c2fef83..9860cd5b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift @@ -31,6 +31,7 @@ import UIKit return formatter }() + /// Update the property value to alter the format of how the date is presented. public var dateFormat: String = "MMM d, y" { didSet { dateFormatter.dateFormat = dateFormat } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 5e874936..d5abbe9f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -67,7 +67,7 @@ import UIKit public var showError: Bool { get { return entryFieldContainer.showError } set (error) { - self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.informativeMessage + self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback self.entryFieldContainer.showError = error } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 1f0e3d78..0da17d96 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -87,7 +87,6 @@ import Foundation } feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) - informativeMessage = feedback if let errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) { self.errorMessage = errorMessage From 9181d3f6d1d30ed83145b53961b4d1b681d4ade6 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 13:05:38 -0400 Subject: [PATCH 18/51] removed unused variable --- MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 0da17d96..1cde6377 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -23,7 +23,6 @@ import Foundation public var title: String = "" public var feedback: String? public var errorMessage: String? - public var informativeMessage: String? public var enabled: Bool = true public var locked: Bool? public var selected: Bool? From e8aaad52876880f3ca5239dce0f00152b5eec20d Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 14:54:00 -0400 Subject: [PATCH 19/51] removing redundancy --- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index c12b92ac..b7d1cb7c 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -38,7 +38,6 @@ private enum CodingKeys: String, CodingKey { case moleculeName - case text case placeholder case enabledTextColor case disabledTextColor @@ -52,7 +51,6 @@ required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - text = try typeContainer.decodeIfPresent(String.self, forKey: .text) placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) @@ -63,7 +61,6 @@ try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) - try container.encodeIfPresent(text, forKey: .text) try container.encodeIfPresent(placeholder, forKey: .placeholder) try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor) try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor) From a083a01dd812f01ee7401447afba453b9734aa96 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 15:14:55 -0400 Subject: [PATCH 20/51] resolving a race condition --- MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index ce36a7cb..ad7c8b49 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -125,7 +125,7 @@ import MVMCore let isValid = hasValidMDN() - if isValid { + if self.isValid { showError = false } else { From e5247ac13f976463f7460ac001c81e14925b4882 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 15:26:44 -0400 Subject: [PATCH 21/51] resolving a race condition --- MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift index ad7c8b49..d80a008b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift @@ -123,7 +123,7 @@ import MVMCore return true } - let isValid = hasValidMDN() + isValid = hasValidMDN() if self.isValid { showError = false From 932a79dea8dada272d190fadcb4d460eabc7041e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 16 Apr 2020 09:05:09 -0400 Subject: [PATCH 22/51] few more improvements to work closer with molecular --- .../ActionCollapseNotificationModel.swift | 2 ++ MVMCoreUI/Actions/ActionOpenPanelModel.swift | 2 ++ MVMCoreUI/Actions/ActionTopAlertModel.swift | 2 ++ .../DateDropdownEntryFieldModel.swift | 4 +--- .../TextFields/DigitEntryFieldModel.swift | 4 +--- .../Atomic/Atoms/TextFields/EntryField.swift | 1 - .../Atoms/TextFields/EntryFieldModel.swift | 18 ++++++++--------- .../ItemDropdownEntryFieldModel.swift | 2 -- .../Atoms/TextFields/TextEntryField.swift | 10 +++------- .../TextFields/TextEntryFieldModel.swift | 20 ++++++++++++------- 10 files changed, 33 insertions(+), 32 deletions(-) diff --git a/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift b/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift index 1a665b80..a305436b 100644 --- a/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift +++ b/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift @@ -9,6 +9,8 @@ import UIKit @objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol { + public var title: String? + public static var identifier: String = "collapseNotification" public var actionType: String public var extraParameters: JSONValueDictionary? diff --git a/MVMCoreUI/Actions/ActionOpenPanelModel.swift b/MVMCoreUI/Actions/ActionOpenPanelModel.swift index 6ada6f04..4e2c26bf 100644 --- a/MVMCoreUI/Actions/ActionOpenPanelModel.swift +++ b/MVMCoreUI/Actions/ActionOpenPanelModel.swift @@ -9,6 +9,8 @@ import Foundation public class ActionOpenPanelModel: ActionModelProtocol { + public var title: String? + public enum Panel: String, Codable { case left diff --git a/MVMCoreUI/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Actions/ActionTopAlertModel.swift index 29838c76..dbcf6371 100644 --- a/MVMCoreUI/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Actions/ActionTopAlertModel.swift @@ -9,6 +9,8 @@ import Foundation @objcMembers public class ActionTopAlertModel: ActionModelProtocol { + public var title: String? + public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier public var pageType: String diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift index 726eab1f..86c072dd 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift @@ -22,12 +22,11 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case dateFormat } //-------------------------------------------------- - // MARK: - Initializers + // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { @@ -42,7 +41,6 @@ public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(moleculeName, forKey: .moleculeName) try container.encode(dateFormat, forKey: .dateFormat) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift index e91eca77..b906244d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift @@ -23,12 +23,11 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case digits } //-------------------------------------------------- - // MARK: - Initializers + // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { @@ -43,7 +42,6 @@ public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(moleculeName, forKey: .moleculeName) try container.encode(digits, forKey: .digits) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index efa0b592..6bb82fe1 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -252,7 +252,6 @@ import UIKit title = model.title feedback = model.feedback - errorMessage = model.errorMessage isEnabled = model.enabled if let isLocked = model.locked { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index f91febf4..d6b7e279 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -20,9 +20,9 @@ import Foundation } public var backgroundColor: Color? - public var title: String = "" + public var title: String? public var feedback: String? - public var errorMessage: String = "" + public var errorMessage: String? public var enabled: Bool = true public var locked: Bool? public var selected: Bool? @@ -77,16 +77,16 @@ import Foundation baseValue = text } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - - if let title = try typeContainer.decodeIfPresent(String.self, forKey: .title) { - self.title = title - } - + title = try typeContainer.decodeIfPresent(String.self, forKey: .title) feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) - errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? "" + errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked) selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) @@ -106,7 +106,7 @@ import Foundation try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(locked, forKey: .locked) try container.encodeIfPresent(selected, forKey: .selected) - try container.encode(errorMessage, forKey: .errorMessage) + try container.encodeIfPresent(errorMessage, forKey: .errorMessage) try container.encode(enabled, forKey: .enabled) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 2f2003c0..8554244b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -23,7 +23,6 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case options case selectedIndex } @@ -48,7 +47,6 @@ public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(moleculeName, forKey: .moleculeName) try container.encode(options, forKey: .options) try container.encode(options, forKey: .selectedIndex) } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 2b68bb6b..0abf4b93 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -49,9 +49,6 @@ import UIKit // MARK: - Stored Properties //-------------------------------------------------- - /// Set enabled and disabled colors to be utilized when setting this texfield's isEnabled property. - public var textColor: (enabled: UIColor?, disabled: UIColor?) = (.mvmBlack, .mvmCoolGray3) - private var observingForChange: Bool = false /// Validate on each entry in the textField. Default: true @@ -77,7 +74,7 @@ import UIKit guard let self = self else { return } self.textField.isEnabled = enabled - self.textField.textColor = enabled ? self.textColor.enabled : self.textColor.disabled + self.textField.textColor = enabled ? self.textEntryFieldModel?.enabledTextColor.uiColor : self.textEntryFieldModel?.disabledTextColor.uiColor } } } @@ -295,6 +292,7 @@ import UIKit } else { errorImage.removeFromSuperview() + textFieldTrailingConstraint?.isActive = false textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two) textFieldTrailingConstraint?.isActive = true } @@ -320,9 +318,7 @@ import UIKit } self.delegateObject = delegateObject - FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) - textColor.enabled = model.enabledTextColor?.uiColor - textColor.disabled = model.disabledTextColor?.uiColor + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) text = model.text placeholder = model.placeholder diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index b7d1cb7c..491e9891 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -28,8 +28,8 @@ } public var placeholder: String? - public var enabledTextColor: Color? - public var disabledTextColor: Color? + public var enabledTextColor: Color = Color(uiColor: .mvmBlack) + public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3) public var type: EntryType? //-------------------------------------------------- @@ -45,16 +45,22 @@ } //-------------------------------------------------- - // MARK: - Initializers + // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) - enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) - disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type) + + if let enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) { + self.enabledTextColor = enabledTextColor + } + + if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) { + self.disabledTextColor = disabledTextColor + } } public override func encode(to encoder: Encoder) throws { @@ -62,8 +68,8 @@ var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(placeholder, forKey: .placeholder) - try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor) - try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor) + try container.encode(enabledTextColor, forKey: .enabledTextColor) + try container.encode(disabledTextColor, forKey: .disabledTextColor) try container.encodeIfPresent(type, forKey: .type) } } From 6b02d04866d695d00ee3b973eeb72668e1599c55 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:20:34 -0400 Subject: [PATCH 23/51] remove title --- MVMCoreUI/Actions/ActionCollapseNotificationModel.swift | 1 - MVMCoreUI/Actions/ActionOpenPanelModel.swift | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift b/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift index a305436b..581c8687 100644 --- a/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift +++ b/MVMCoreUI/Actions/ActionCollapseNotificationModel.swift @@ -9,7 +9,6 @@ import UIKit @objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol { - public var title: String? public static var identifier: String = "collapseNotification" public var actionType: String diff --git a/MVMCoreUI/Actions/ActionOpenPanelModel.swift b/MVMCoreUI/Actions/ActionOpenPanelModel.swift index 4e2c26bf..9149b32b 100644 --- a/MVMCoreUI/Actions/ActionOpenPanelModel.swift +++ b/MVMCoreUI/Actions/ActionOpenPanelModel.swift @@ -9,9 +9,7 @@ import Foundation public class ActionOpenPanelModel: ActionModelProtocol { - public var title: String? - - + public enum Panel: String, Codable { case left case right From 8c662a0992f21d0a5410b89fd05ef49260d3acb7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:22:54 -0400 Subject: [PATCH 24/51] remove title --- MVMCoreUI/Actions/ActionTopAlertModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Actions/ActionTopAlertModel.swift index dbcf6371..82d9fa17 100644 --- a/MVMCoreUI/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Actions/ActionTopAlertModel.swift @@ -9,7 +9,6 @@ import Foundation @objcMembers public class ActionTopAlertModel: ActionModelProtocol { - public var title: String? public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier From 11d1515a46ba3c8a9378ce3f4da24960f75b9ccc Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:34:55 -0400 Subject: [PATCH 25/51] path based on delegate existence --- .../Atomic/Atoms/TextFields/DigitEntryField.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index aff5ec75..5fa17417 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -335,8 +335,14 @@ import UIKit } for digitBox in digitBoxes { - digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self, - action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + + if let observingTextFieldelegate = delegateObject?.observingTextFieldDelegate { + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldelegate, + action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + } else { + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: self, + action: #selector(dismissFieldInput)) + } } super.set(with: model, delegateObject, additionalData) From 554be6cc671e2a2bb3ad047a18bcec5186a091a6 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:35:47 -0400 Subject: [PATCH 26/51] path based on delegate existence --- MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 5fa17417..977447ff 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -338,7 +338,7 @@ import UIKit if let observingTextFieldelegate = delegateObject?.observingTextFieldDelegate { digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldelegate, - action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + action: #selector(observingTextFieldelegate.dismissFieldInput)) } else { digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: self, action: #selector(dismissFieldInput)) From 7c22229c2b5d6b0216a13b88d17e3c16d8af8e85 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:42:42 -0400 Subject: [PATCH 27/51] path based on delegate existence --- .../Atoms/TextFields/DigitEntryField.swift | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 977447ff..01305a95 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -334,17 +334,13 @@ import UIKit setAsSecureTextEntry(entryType == .secure || entryType == .password) } - for digitBox in digitBoxes { - - if let observingTextFieldelegate = delegateObject?.observingTextFieldDelegate { - digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldelegate, - action: #selector(observingTextFieldelegate.dismissFieldInput)) - } else { - digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: self, - action: #selector(dismissFieldInput)) - } - } + let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self + digitBoxes.forEach { + $0.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, + action: #selector(observingDelegate.dismissFieldInput)) + } + super.set(with: model, delegateObject, additionalData) } From 1437bc60180f3b0442e28680a919b578bce1b290 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 14:47:50 -0400 Subject: [PATCH 28/51] path based on delegate existence --- MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift index 01305a95..8ae4365f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift @@ -211,8 +211,9 @@ import UIKit let digitBox = DigitBox() digitBox.isAccessibilityElement = true - digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, - action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self + digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, + action: #selector(observingDelegate.dismissFieldInput)) digitBox.digitField.delegate = self digitBox.digitBoxDelegate = self return digitBox From c8f0341e4c9bdb3fed9f45efdf60257c337e2530 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 15:54:27 -0400 Subject: [PATCH 29/51] bringing back groupname --- MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index d6b7e279..4e9cfb7e 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -93,6 +93,9 @@ import Foundation text = try typeContainer.decodeIfPresent(String.self, forKey: .text) baseValue = text fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } } public func encode(to encoder: Encoder) throws { From c8b4eaac067a3e10a196da77937e564f21bef8f4 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 16:26:42 -0400 Subject: [PATCH 30/51] moved code. changed options --- MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift | 4 ++-- .../Atoms/TextFields/ItemDropdownEntryFieldModel.swift | 4 +--- MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 4e9cfb7e..337d847d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -105,11 +105,11 @@ import Foundation try container.encodeIfPresent(title, forKey: .title) try container.encodeIfPresent(feedback, forKey: .feedback) try container.encodeIfPresent(text, forKey: .text) - try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(locked, forKey: .locked) try container.encodeIfPresent(selected, forKey: .selected) try container.encodeIfPresent(errorMessage, forKey: .errorMessage) try container.encode(enabled, forKey: .enabled) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 8554244b..ac7fbab1 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -35,9 +35,7 @@ try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - if let options = try typeContainer.decodeIfPresent([String].self, forKey: .options) { - self.options = options - } + options = try typeContainer.decode([String].self, forKey: .options) if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) { self.selectedIndex = selectedIndex diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 0abf4b93..f95c918d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -214,9 +214,9 @@ import UIKit } open func setupTextFieldToolbar() { - - textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self, - action: #selector(observingTextFieldDelegate?.dismissFieldInput)) + let observingDelegate = observingTextFieldDelegate ?? self + textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, + action: #selector(observingDelegate.dismissFieldInput)) } //-------------------------------------------------- From 81cef4fdf15edf5a6ad30a67a0faaa59f65b0bed Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 17:24:18 -0400 Subject: [PATCH 31/51] beginning changes --- .../ToggleMolecules/LabelToggle.swift | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift index 9ce24d3b..17a645ed 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift @@ -9,10 +9,17 @@ import UIKit @objcMembers open class LabelToggle: View { - public let label = Label.commonLabelB1(true) + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public let label = Label.createLabelBoldBodySmall(true) public let toggle = Toggle() + //-------------------------------------------------- // MARK: - MVMCoreViewProtocol + //-------------------------------------------------- + open override func updateView(_ size: CGFloat) { super.updateView(size) label.updateView(size) @@ -21,17 +28,13 @@ import UIKit open override func setupView() { super.setupView() - guard toggle.superview == nil else { - return - } addSubview(label) addSubview(toggle) - label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) + label.setContentHuggingPriority(.required, for: .vertical) NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false) } - // MARK:- MoleculeViewProtocol open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? LabelToggleModel, let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), @@ -40,9 +43,9 @@ import UIKit } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let labelToggleModel = model as? LabelToggleModel else { - return - } + + guard let labelToggleModel = model as? LabelToggleModel else { return } + label.set(with: labelToggleModel.label, delegateObject, additionalData) toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData) } @@ -52,6 +55,6 @@ import UIKit super.reset() label.reset() toggle.reset() - label.styleB1(true) + label.styleBoldBodySmall(true) } } From 82c7b372c94eb638e0ddfd8e9e7e8f07f0ed1237 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 17:36:16 -0400 Subject: [PATCH 32/51] latest --- MVMCoreUI/Atomic/Atoms/Views/Toggle.swift | 30 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift index 75e9675a..c14e20fc 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift @@ -131,8 +131,31 @@ public typealias ActionBlockConfirmation = () -> (Bool) private var widthConstraint: NSLayoutConstraint? private func constrainKnob() { - knobLeadingConstraint?.isActive = !isOn - knobTrailingConstraint?.isActive = isOn + + knobLeadingConstraint?.isActive = false + knobTrailingConstraint?.isActive = false + + if isOn { + constrainKnobOn() + + } else { + constrainKnobOff() + } + + knobTrailingConstraint?.isActive = true + knobLeadingConstraint?.isActive = true + } + + private func constrainKnobOn() { + + knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1) + knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor) + } + + private func constrainKnobOff() { + + knobTrailingConstraint = trailingAnchor.constraint(greaterThanOrEqualTo: knobView.trailingAnchor) + knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1) } //-------------------------------------------------- @@ -218,8 +241,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true - knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1) - knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1) + constrainKnobOff() knobLeadingConstraint?.isActive = true } From d8d691f2cc5267f0b0725b2b7b5eea84896896e1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 17:46:50 -0400 Subject: [PATCH 33/51] resolvong a constraint issue --- MVMCoreUI/Atomic/Atoms/Views/Toggle.swift | 8 +------- .../LeftRightViews/ToggleMolecules/LabelToggle.swift | 5 ++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift index c14e20fc..eab07e0f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift @@ -135,12 +135,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) knobLeadingConstraint?.isActive = false knobTrailingConstraint?.isActive = false - if isOn { - constrainKnobOn() - - } else { - constrainKnobOff() - } + _ = isOn ? constrainKnobOn() : constrainKnobOff() knobTrailingConstraint?.isActive = true knobLeadingConstraint?.isActive = true @@ -242,7 +237,6 @@ public typealias ActionBlockConfirmation = () -> (Bool) bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true constrainKnobOff() - knobLeadingConstraint?.isActive = true } public override func reset() { diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift index 17a645ed..3ff3a41f 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift @@ -8,6 +8,7 @@ import UIKit + @objcMembers open class LabelToggle: View { //-------------------------------------------------- // MARK: - Properties @@ -38,7 +39,9 @@ import UIKit open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? LabelToggleModel, let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), - let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) else { return nil } + let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) + else { return nil } + return max(toggleHeight, labelHeight) } From 630c51d83b9c57bce434eede900f069a5772e8cb Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 17:57:59 -0400 Subject: [PATCH 34/51] changes for refrsh --- MVMCoreUI/Atomic/Atoms/Views/Toggle.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift index eab07e0f..8efd0a3c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift @@ -207,6 +207,8 @@ public typealias ActionBlockConfirmation = () -> (Bool) layer.cornerRadius = Self.getContainerHeight() / 2.0 knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0 + + changeStateNoAnimation(isOn) } public override func setupView() { @@ -245,8 +247,6 @@ public typealias ActionBlockConfirmation = () -> (Bool) backgroundColor = containerTintColor.off knobView.backgroundColor = knobTintColor.off isAnimated = true - isOn = false - constrainKnob() didToggleAction = nil shouldToggleAction = { return true } } @@ -368,7 +368,8 @@ public typealias ActionBlockConfirmation = () -> (Bool) containerTintColor.off = model.offTintColor.uiColor knobTintColor.on = model.onKnobTintColor.uiColor knobTintColor.off = model.offKnobTintColor.uiColor - changeStateNoAnimation(model.state) + isOn = model.state + changeStateNoAnimation(isOn) isAnimated = model.animated isEnabled = model.enabled From 5f17e909217ac125cc3655040c9453963c6c8744 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 18:28:03 -0400 Subject: [PATCH 35/51] code compression --- MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift index 49826504..cad763a6 100644 --- a/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift @@ -40,10 +40,7 @@ public extension UIToolbar { class func addDismissToolbar(to object: TextFieldOrView, delegate: Any?, action: Selector) { - let toolbar = createEmptyToolbar() - let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action) - toolbar.items = [space, dismissButton] + let toolbar = Self.getToolbarWithDoneButton(delegate: delegate, action: action) switch object { case is UITextField: From e5a5415dd3a8ac26804db152404794acd916e24e Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 21 Apr 2020 11:06:25 +0530 Subject: [PATCH 36/51] initial commi --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 4 + .../List/ListDeviceComplexButtonMedium.swift | 72 ++++++++++++++++++ .../ListDeviceComplexButtonMediumModel.swift | 75 +++++++++++++++++++ 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index fe06c483..64c9ff42 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -151,7 +151,7 @@ 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* Wheel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* Wheel.swift */; }; 943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */; }; - 943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; }; + 943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; }; 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94382085243238D100B43AF3 /* WebViewModel.swift */; }; 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; }; 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */; }; @@ -199,6 +199,8 @@ AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; + BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; }; + BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; }; BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; }; BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; @@ -635,6 +637,8 @@ AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; + BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = ""; }; + BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = ""; }; BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = ""; }; BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = ""; }; BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = ""; }; @@ -1351,6 +1355,8 @@ D22B38EA23F4E08B00490EF6 /* List */ = { isa = PBXGroup; children = ( + BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */, + BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */, 52267A0523FFE0A900906CBA /* OneColumn */, D22D8396241FDE4700D3DF69 /* TwoColumn */, 8DD1E36C243B3CD900D8F2DF /* ThreeColumn */, @@ -2149,6 +2155,7 @@ D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */, D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */, AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */, + BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */, 014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */, @@ -2197,7 +2204,7 @@ D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */, D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */, - EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */, + EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */, D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */, DBEFFA04225A829700230692 /* Label.swift in Sources */, D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */, @@ -2392,6 +2399,7 @@ D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */, C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, + BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 2e98d344..748dfced 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -166,6 +166,10 @@ import Foundation // Designed Headers MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self) + + + // Device Items + MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self) // TODO: Need View try? ModelRegistry.register(TabsModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift new file mode 100644 index 00000000..435ef03f --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift @@ -0,0 +1,72 @@ +// +// ListDeviceComplexButtonMedium.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 21/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers open class ListDeviceComplexButtonMedium: TableViewCell { + + public var stack: Stack + public let eyebrow = Label.commonLabelB3(true) + public let headline = Label.commonLabelB1(true) + public let body = Label.commonLabelB2(true) + public let body2 = Label.commonLabelB2(true) + public let button = Button(frame: .zero) + public let rightImageView = MFLoadImageView(pinnedEdges: .all) + public var imageViewStack: Stack + + + + // MARK: - Initializers + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), + (view: headline, model: StackItemModel(horizontalAlignment: .leading)), + (view: body, model: StackItemModel(horizontalAlignment: .leading)), + (view: body2, model: StackItemModel(horizontalAlignment: .leading)), + (view: button, model: StackItemModel(horizontalAlignment: .leading))], + axis: .vertical) + imageViewStack = Stack.createStack(with: [(view: stack, model: StackItemModel(horizontalAlignment: .leading)), + (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], + axis: .horizontal,spacing: 10) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - MFViewProtocol + open override func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + // MARK: - ModelMoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListDeviceComplexButtonMediumModel else { return } + eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData) + headline.setOptional(with: model.headline, delegateObject, additionalData) + body.setOptional(with: model.body, delegateObject, additionalData) + body2.setOptional(with: model.body, delegateObject, additionalData) + button.set(with: model.button, delegateObject, additionalData) + rightImageView.set(with: model.image, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 120 + } + + open override func reset() { + super.reset() + eyebrow.styleRegularMicro(true) + headline.styleBoldTitleMedium(true) + body.styleRegularBodySmall(true) + body2.styleRegularBodySmall(true) + + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift new file mode 100644 index 00000000..5325f8ee --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift @@ -0,0 +1,75 @@ +// +// ListDeviceComplexButtonMediumModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 21/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +public class ListDeviceComplexButtonMediumModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listDvcBtnM" + public var eyebrow: LabelModel? + public var headline: LabelModel? + public var body: LabelModel? + public var body2: LabelModel? + public var button: ButtonModel + public var image: ImageViewModel + + + + public init(eyebrow: LabelModel, headline:LabelModel, body: LabelModel, body2: LabelModel, button: ButtonModel, image: ImageViewModel) { + self.eyebrow = eyebrow + self.headline = headline + self.body = body + self.body2 = body2 + self.button = button + self.image = image + super.init() + } + + /// Defaults to set + override public func setDefaults() { + super.setDefaults() + eyebrow?.fontStyle = .RegularMicro + eyebrow?.textColor = Color(uiColor: .mvmCoolGray6) + headline?.fontStyle = .BoldTitleMedium + body?.fontStyle = .RegularBodySmall + body2?.fontStyle = .RegularBodySmall + button.size = .tiny + button.style = .secondary + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case eyebrow + case headline + case body + case body2 + case button + case image + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) + headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline) + body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body) + body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2) + button = try typeContainer.decode(ButtonModel.self, forKey: .button) + image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(eyebrow, forKey: .eyebrow) + try container.encodeIfPresent(headline, forKey: .headline) + try container.encodeIfPresent(body, forKey: .body) + try container.encodeIfPresent(body2, forKey: .body2) + try container.encode(button, forKey: .button) + try container.encode(image, forKey: .image) + } +} From 5a4805d1a4fb27c76fe5857aa550fd0a354626a6 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 21 Apr 2020 16:26:59 +0530 Subject: [PATCH 37/51] Applied styles as per confluence --- .../List/ListDeviceComplexButtonMedium.swift | 43 +++++++++++-------- .../ListDeviceComplexButtonMediumModel.swift | 7 --- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift index 435ef03f..3d1971fa 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift @@ -9,28 +9,31 @@ import Foundation @objcMembers open class ListDeviceComplexButtonMedium: TableViewCell { - public var stack: Stack + public var verticalStack: Stack public let eyebrow = Label.commonLabelB3(true) public let headline = Label.commonLabelB1(true) public let body = Label.commonLabelB2(true) public let body2 = Label.commonLabelB2(true) - public let button = Button(frame: .zero) + public let button = PillButton(frame: .zero) public let rightImageView = MFLoadImageView(pinnedEdges: .all) - public var imageViewStack: Stack - + public var stack: Stack + // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - stack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), - (view: headline, model: StackItemModel(horizontalAlignment: .leading)), - (view: body, model: StackItemModel(horizontalAlignment: .leading)), - (view: body2, model: StackItemModel(horizontalAlignment: .leading)), - (view: button, model: StackItemModel(horizontalAlignment: .leading))], - axis: .vertical) - imageViewStack = Stack.createStack(with: [(view: stack, model: StackItemModel(horizontalAlignment: .leading)), - (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], - axis: .horizontal,spacing: 10) + rightImageView.heightAnchor.constraint(equalToConstant: 116.0).isActive = true + rightImageView.widthAnchor.constraint(equalToConstant: 116.0).isActive = true + + verticalStack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), + (view: headline, model: StackItemModel(horizontalAlignment: .leading)), + (view: body, model: StackItemModel(horizontalAlignment: .leading)), + (view: body2, model: StackItemModel(horizontalAlignment: .leading)), + (view: button, model: StackItemModel(spacing:10,horizontalAlignment: .leading))], + axis: .vertical,spacing: 0) + stack = Stack.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading,verticalAlignment: .center)), + (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], + axis: .horizontal,spacing: 10) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -43,6 +46,7 @@ import Foundation super.setupView() addMolecule(stack) stack.restack() + verticalStack.restack() } // MARK: - ModelMoleculeViewProtocol @@ -52,7 +56,7 @@ import Foundation eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData) headline.setOptional(with: model.headline, delegateObject, additionalData) body.setOptional(with: model.body, delegateObject, additionalData) - body2.setOptional(with: model.body, delegateObject, additionalData) + body2.setOptional(with: model.body2, delegateObject, additionalData) button.set(with: model.button, delegateObject, additionalData) rightImageView.set(with: model.image, delegateObject, additionalData) } @@ -60,13 +64,16 @@ import Foundation open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return 120 } - - open override func reset() { - super.reset() + public func setDefault() { eyebrow.styleRegularMicro(true) headline.styleBoldTitleMedium(true) body.styleRegularBodySmall(true) body2.styleRegularBodySmall(true) - + eyebrow.textColor = .mvmCoolGray6 + } + + open override func reset() { + super.reset() + setDefault() } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift index 5325f8ee..7f676795 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift @@ -15,8 +15,6 @@ public class ListDeviceComplexButtonMediumModel: ListItemModel, MoleculeModelPro public var body2: LabelModel? public var button: ButtonModel public var image: ImageViewModel - - public init(eyebrow: LabelModel, headline:LabelModel, body: LabelModel, body2: LabelModel, button: ButtonModel, image: ImageViewModel) { self.eyebrow = eyebrow @@ -31,11 +29,6 @@ public class ListDeviceComplexButtonMediumModel: ListItemModel, MoleculeModelPro /// Defaults to set override public func setDefaults() { super.setDefaults() - eyebrow?.fontStyle = .RegularMicro - eyebrow?.textColor = Color(uiColor: .mvmCoolGray6) - headline?.fontStyle = .BoldTitleMedium - body?.fontStyle = .RegularBodySmall - body2?.fontStyle = .RegularBodySmall button.size = .tiny button.style = .secondary } From c2c612aba85e0ea46ab212b879ed950fb0b7a970 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 21 Apr 2020 10:59:35 -0400 Subject: [PATCH 38/51] fix break to background color --- MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift | 3 +++ MVMCoreUI/Atomic/Organisms/StackModel.swift | 2 ++ 2 files changed, 5 insertions(+) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift index dc01fd11..1a6bced6 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift @@ -17,6 +17,7 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName + case backgroundColor case spacing case percent case gone @@ -33,6 +34,7 @@ import Foundation if let gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone) { self.gone = gone } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) } @@ -43,5 +45,6 @@ import Foundation try container.encodeIfPresent(spacing, forKey: .spacing) try container.encodeIfPresent(percent, forKey: .percent) try container.encode(gone, forKey: .gone) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } diff --git a/MVMCoreUI/Atomic/Organisms/StackModel.swift b/MVMCoreUI/Atomic/Organisms/StackModel.swift index cc8f7d0e..3f13a580 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModel.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModel.swift @@ -48,6 +48,7 @@ import Foundation if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) { self.spacing = spacing } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) } @@ -58,5 +59,6 @@ import Foundation try container.encodeIfPresent(axis.rawValueString, forKey: .axis) try container.encodeIfPresent(spacing, forKey: .spacing) try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } From 5268e6356c44caa15364a1898355a45a1db0c88e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 21 Apr 2020 13:03:15 -0400 Subject: [PATCH 39/51] correcting spacing issue --- MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index 4ebfd013..d5ad9a83 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -198,7 +198,7 @@ [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=space-[button]->=space-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(PaddingFive)} views:NSDictionaryOfVariableBindings(button)]]; [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:PaddingThree].active = YES; - [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)].active = YES; + [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)].active = YES; self.button = button; } } else { @@ -210,7 +210,7 @@ } if (!self.labelRightConstraint) { - self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)]; + self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)]; } self.labelRightConstraint.active = YES; } From 02a39a2f913dd49dfabc88f596eb358b33f3841d Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 21 Apr 2020 14:52:58 -0400 Subject: [PATCH 40/51] slection --- .../Atoms/TextFields/ItemDropdownEntryFieldModel.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index ac7fbab1..345817fd 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -17,6 +17,10 @@ public var options: [String] = [] public var selectedIndex: Int = 0 + + public override func formFieldValue() -> AnyHashable? { + return options[selectedIndex] + } //-------------------------------------------------- // MARK: - Keys @@ -26,7 +30,7 @@ case options case selectedIndex } - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- From db61701c2c0478c8d4e5af6b7ce782950475ba3a Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 21 Apr 2020 15:09:40 -0400 Subject: [PATCH 41/51] guard --- .../Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 345817fd..2105120c 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -18,7 +18,8 @@ public var options: [String] = [] public var selectedIndex: Int = 0 - public override func formFieldValue() -> AnyHashable? { + public override func formFieldValue() -> AnyHashable? { + guard !options.isEmpty else { return nil } return options[selectedIndex] } From 7b3bb5ffb20433d888b560c523f8b8eee8316457 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 22 Apr 2020 11:00:31 +0530 Subject: [PATCH 42/51] label font changes updated --- .../List/ListDeviceComplexButtonMedium.swift | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift index 3d1971fa..9847a7a8 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift @@ -10,26 +10,23 @@ import Foundation @objcMembers open class ListDeviceComplexButtonMedium: TableViewCell { public var verticalStack: Stack - public let eyebrow = Label.commonLabelB3(true) - public let headline = Label.commonLabelB1(true) - public let body = Label.commonLabelB2(true) - public let body2 = Label.commonLabelB2(true) + public let eyebrow = Label.createLabelRegularMicro(true) + public let headline = Label.createLabelBoldTitleMedium(true) + public let body = Label.createLabelRegularBodySmall(true) + public let body2 = Label.createLabelRegularBodySmall(true) public let button = PillButton(frame: .zero) public let rightImageView = MFLoadImageView(pinnedEdges: .all) public var stack: Stack - - // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { rightImageView.heightAnchor.constraint(equalToConstant: 116.0).isActive = true rightImageView.widthAnchor.constraint(equalToConstant: 116.0).isActive = true - - verticalStack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), + verticalStack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), - (view: button, model: StackItemModel(spacing:10,horizontalAlignment: .leading))], + (view: button, model: StackItemModel(spacing:16,horizontalAlignment: .leading))], axis: .vertical,spacing: 0) stack = Stack.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading,verticalAlignment: .center)), (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], From 211e3b6e586066f2f4790925d7b1dd31de9e4234 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Wed, 22 Apr 2020 11:27:11 +0530 Subject: [PATCH 43/51] 19024 - List - Three Column - Data Usage - Initial commit --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../ListThreeColumnDataUsage.swift | 61 +++++++++++++++++++ .../ListThreeColumnDataUsageModel.swift | 48 +++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsageModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 767e9f32..3cf7884e 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -143,6 +143,8 @@ 8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */; }; 8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */; }; 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */; }; + 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */; }; + 8DDD6C1F244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */; }; 8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */; }; 8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */; }; 942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; }; @@ -581,6 +583,8 @@ 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinks.swift; sourceTree = ""; }; 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalDataModel.swift; sourceTree = ""; }; 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalData.swift; sourceTree = ""; }; + 8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsage.swift; sourceTree = ""; }; + 8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageModel.swift; sourceTree = ""; }; 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDividerModel.swift; sourceTree = ""; }; 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDivider.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; @@ -1067,6 +1071,8 @@ children = ( 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */, 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */, + 8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */, + 8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */, ); path = ThreeColumn; sourceTree = ""; @@ -2188,6 +2194,7 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */, 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, + 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */, AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */, @@ -2196,6 +2203,7 @@ 525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */, D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */, 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */, + 8DDD6C1F244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift in Sources */, BB55B51F244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift in Sources */, D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */, D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index e31e18a1..8026dfec 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -152,6 +152,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self) // Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift new file mode 100644 index 00000000..0884997a --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift @@ -0,0 +1,61 @@ +// +// ListThreeColumnDataUsage.swift +// MVMCoreUI +// +// Created by Kruthika KP on 20/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListThreeColumnDataUsage: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //------------------------------------------------------- + public let leftLabel = Label.createLabelRegularBodySmall(true) + public let centerLabel = Label.createLabelRegularBodySmall(true) + public let rightLabel = Label.createLabelRegularBodySmall(true) + var stack: Stack + + //------------------------------------------------------ + // MARK: - Initializers + //------------------------------------------------------ + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 37, horizontalAlignment: .leading)), + (view: centerLabel, model: StackItemModel(percent: 33, horizontalAlignment: .leading)), + (view: rightLabel, model: StackItemModel(percent: 30, horizontalAlignment: .leading))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open override func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + // MARK: - ModelMoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListThreeColumnDataUsageModel else { return } + leftLabel.set(with: model.leftLabel, delegateObject, additionalData) + centerLabel.set(with: model.centerLabel, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 121 + } + + open override func reset() { + super.reset() + leftLabel.styleBoldBodySmall(true) + centerLabel.styleBoldBodySmall(true) + rightLabel.styleBoldBodySmall(true) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsageModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsageModel.swift new file mode 100644 index 00000000..56f1e402 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsageModel.swift @@ -0,0 +1,48 @@ +// +// ListThreeColumnDataUsageModel.swift +// MVMCoreUI +// +// Created by Kruthika KP on 20/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListThreeColumnDataUsageModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "list3CDataUsg" + public var leftLabel: LabelModel + public var centerLabel: LabelModel + public var rightLabel: LabelModel + + public init(leftLabel:LabelModel, centerLabel:LabelModel, rightLabel:LabelModel) { + self.leftLabel = leftLabel + self.centerLabel = centerLabel + self.rightLabel = rightLabel + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case leftLabel + case centerLabel + case rightLabel + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) + centerLabel = try typeContainer.decode(LabelModel.self, forKey: .centerLabel) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(leftLabel, forKey: .leftLabel) + try container.encode(centerLabel, forKey: .centerLabel) + try container.encode(rightLabel, forKey: .rightLabel) + } +} + From 0ceb0e97393c638339989dab3e30f437cb27aef4 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 22 Apr 2020 15:10:17 +0530 Subject: [PATCH 44/51] spacing between stack items modified --- .../DesignedComponents/List/ListDeviceComplexButtonMedium.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift index 9847a7a8..90e0fc60 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift @@ -30,7 +30,7 @@ import Foundation axis: .vertical,spacing: 0) stack = Stack.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading,verticalAlignment: .center)), (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], - axis: .horizontal,spacing: 10) + axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } From 59622ac372b351306ff9bbc279fc138f200ce25a Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Wed, 22 Apr 2020 17:02:06 +0530 Subject: [PATCH 45/51] style change --- .../List/ThreeColumn/ListThreeColumnDataUsage.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift index 0884997a..2611943a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift @@ -22,9 +22,9 @@ import Foundation // MARK: - Initializers //------------------------------------------------------ public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 37, horizontalAlignment: .leading)), - (view: centerLabel, model: StackItemModel(percent: 33, horizontalAlignment: .leading)), - (view: rightLabel, model: StackItemModel(percent: 30, horizontalAlignment: .leading))], + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 35, horizontalAlignment: .leading)), + (view: centerLabel, model: StackItemModel(percent: 35, horizontalAlignment: .leading)), + (view: rightLabel, model: StackItemModel(percent: 30, horizontalAlignment: .center))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -54,8 +54,8 @@ import Foundation open override func reset() { super.reset() - leftLabel.styleBoldBodySmall(true) - centerLabel.styleBoldBodySmall(true) - rightLabel.styleBoldBodySmall(true) + leftLabel.styleRegularBodySmall(true) + centerLabel.styleRegularBodySmall(true) + rightLabel.styleRegularBodySmall(true) } } From 5a26ce2529f196b26e7fc0416e33e893fecae06b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 22 Apr 2020 14:01:32 -0400 Subject: [PATCH 46/51] accessibility for toggle --- MVMCoreUI/Atomic/Atoms/Views/Toggle.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift index 8efd0a3c..14cfb7b7 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift @@ -246,6 +246,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) backgroundColor = containerTintColor.off knobView.backgroundColor = knobTintColor.off + accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") isAnimated = true didToggleAction = nil shouldToggleAction = { return true } @@ -373,6 +374,10 @@ public typealias ActionBlockConfirmation = () -> (Bool) isAnimated = model.animated isEnabled = model.enabled + if let accessibileString = model.accessibilityText { + accessibilityLabel = accessibileString + } + if let actionMap = model.action?.toJSON() { didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } From ea6dd35952b2299cc328b30757a690d6a948b822 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Thu, 23 Apr 2020 15:09:51 +0530 Subject: [PATCH 47/51] code alignment --- .../DesignedComponents/List/ListDeviceComplexButtonMedium.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift index 90e0fc60..441fc55f 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift @@ -61,6 +61,7 @@ import Foundation open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return 120 } + public func setDefault() { eyebrow.styleRegularMicro(true) headline.styleBoldTitleMedium(true) From a89511f10ca1fe919ad7edff5a04ef2bf377fe09 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 23 Apr 2020 10:43:55 -0400 Subject: [PATCH 48/51] code fixes --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 +- .../List/ThreeColumn/ListThreeColumnDataUsage.swift | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 66e6ff3f..7c57fd40 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -150,8 +150,8 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDetails.self, viewModelClass: ListTwoColumnPriceDetailsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) // Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift index 2611943a..5e7d39c6 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnDataUsage.swift @@ -22,9 +22,9 @@ import Foundation // MARK: - Initializers //------------------------------------------------------ public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 35, horizontalAlignment: .leading)), - (view: centerLabel, model: StackItemModel(percent: 35, horizontalAlignment: .leading)), - (view: rightLabel, model: StackItemModel(percent: 30, horizontalAlignment: .center))], + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 40, horizontalAlignment: .leading)), + (view: centerLabel, model: StackItemModel(percent: 37, horizontalAlignment: .leading)), + (view: rightLabel, model: StackItemModel(percent: 23, horizontalAlignment: .leading))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } From ee1d847a41f264a156e8177f5e92f2f0e6bc53c7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 23 Apr 2020 11:43:55 -0400 Subject: [PATCH 49/51] minor --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++++++++++-- .../{ => Device}/ListDeviceComplexButtonMedium.swift | 8 ++++---- .../ListDeviceComplexButtonMediumModel.swift | 0 3 files changed, 14 insertions(+), 6 deletions(-) rename MVMCoreUI/Atomic/Molecules/DesignedComponents/List/{ => Device}/ListDeviceComplexButtonMedium.swift (92%) rename MVMCoreUI/Atomic/Molecules/DesignedComponents/List/{ => Device}/ListDeviceComplexButtonMediumModel.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 6b8d0855..e98e8f7e 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1172,6 +1172,15 @@ path = FourColumn; sourceTree = ""; }; + D20FFFB42451E32100A31DA2 /* Device */ = { + isa = PBXGroup; + children = ( + BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */, + BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */, + ); + path = Device; + sourceTree = ""; + }; D213347423842FE3008E41B3 /* Controllers */ = { isa = PBXGroup; children = ( @@ -1370,8 +1379,7 @@ D22B38EA23F4E08B00490EF6 /* List */ = { isa = PBXGroup; children = ( - BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */, - BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */, + D20FFFB42451E32100A31DA2 /* Device */, 52267A0523FFE0A900906CBA /* OneColumn */, D22D8396241FDE4700D3DF69 /* TwoColumn */, 8DD1E36C243B3CD900D8F2DF /* ThreeColumn */, diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift similarity index 92% rename from MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift rename to MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift index 441fc55f..a62a6d9b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift @@ -26,10 +26,10 @@ import Foundation (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), - (view: button, model: StackItemModel(spacing:16,horizontalAlignment: .leading))], - axis: .vertical,spacing: 0) - stack = Stack.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading,verticalAlignment: .center)), - (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill,verticalAlignment: .center))], + (view: button, model: StackItemModel(spacing:16, horizontalAlignment: .leading))], + axis: .vertical, spacing: 0) + stack = Stack.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)), + (view: rightImageView, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMediumModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListDeviceComplexButtonMediumModel.swift rename to MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMediumModel.swift From be0c9b874288f0e295a6355022c7eb4e3fa36388 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 23 Apr 2020 12:25:26 -0400 Subject: [PATCH 50/51] Image stretch fix New convenience function for set/gone/restack --- .../ListDeviceComplexButtonMedium.swift | 14 +++++----- MVMCoreUI/Atomic/Organisms/Stack.swift | 26 +++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift index a62a6d9b..f8ab918d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift @@ -15,11 +15,12 @@ import Foundation public let body = Label.createLabelRegularBodySmall(true) public let body2 = Label.createLabelRegularBodySmall(true) public let button = PillButton(frame: .zero) - public let rightImageView = MFLoadImageView(pinnedEdges: .all) + public let rightImageView = MFLoadImageView() public var stack: Stack // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + rightImageView.addSizeConstraintsForAspectRatio = true rightImageView.heightAnchor.constraint(equalToConstant: 116.0).isActive = true rightImageView.widthAnchor.constraint(equalToConstant: 116.0).isActive = true verticalStack = Stack.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), @@ -50,11 +51,12 @@ import Foundation open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListDeviceComplexButtonMediumModel else { return } - eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData) - headline.setOptional(with: model.headline, delegateObject, additionalData) - body.setOptional(with: model.body, delegateObject, additionalData) - body2.setOptional(with: model.body2, delegateObject, additionalData) - button.set(with: model.button, delegateObject, additionalData) + verticalStack.updateContainedMolecules(with: [model.eyebrow, + model.headline, + model.body, + model.body2, + model.button], + delegateObject, additionalData) rightImageView.set(with: model.image, delegateObject, additionalData) } diff --git a/MVMCoreUI/Atomic/Organisms/Stack.swift b/MVMCoreUI/Atomic/Organisms/Stack.swift index f539cf8b..ad961586 100644 --- a/MVMCoreUI/Atomic/Organisms/Stack.swift +++ b/MVMCoreUI/Atomic/Organisms/Stack.swift @@ -62,6 +62,32 @@ open class Stack: Container where T: (StackModelProtocol & MoleculeModelProto } } + /// A convenience function for when the stackItems are containers and we want to update them based on the contained molecules models. If model is nil, stackItem is set to gone. Restacks if necessary. + open func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard var stackModel = stackModel else { return } + var needsRestack = false + for (index, item) in stackItems.enumerated() { + guard let container = item as? UIView & ContainerProtocol, + let contained = container.view as? MoleculeViewProtocol else { + continue + } + if let model = models[index] { + contained.set(with: model, delegateObject, additionalData) + if stackModel.molecules[index].gone { + stackModel.molecules[index].gone = false + needsRestack = true + } + } else if !stackModel.molecules[index].gone { + stackModel.molecules[index].gone = true + needsRestack = true + } + } + + if needsRestack { + restack() + } + } + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- From 4b23a63823f8440fd45172f424e0149b3ddf4b80 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 23 Apr 2020 12:30:07 -0400 Subject: [PATCH 51/51] update others --- ...neColumnFullWidthTextAllTextAndLinks.swift | 20 +++++++------------ .../EyebrowHeadlineBodyLink.swift | 18 ++++++----------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift index 1ea1a4a9..ad74039a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift @@ -40,24 +40,18 @@ import Foundation override open func setupView() { super.setupView() addMolecule(stack) + stack.restack() } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){ super.set(with: model, delegateObject, additionalData) guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return } - eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData) - headline.setOptional(with: model.headline, delegateObject, additionalData) - subHeadline.setOptional(with: model.subHeadline, delegateObject, additionalData) - body.setOptional(with: model.body, delegateObject, additionalData) - link.setOptional(with: model.link, delegateObject, additionalData) - - // Hide labels if neeeded. - stack.stackModel?.molecules[0].gone = !eyebrow.hasText - stack.stackModel?.molecules[1].gone = !headline.hasText - stack.stackModel?.molecules[2].gone = !subHeadline.hasText - stack.stackModel?.molecules[3].gone = !body.hasText - stack.stackModel?.molecules[4].gone = (link.titleLabel?.text?.count ?? 0) == 0 - stack.restack() + stack.updateContainedMolecules(with: [model.eyebrow, + model.headline, + model.subHeadline, + model.body, + model.link], + delegateObject, additionalData) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index 82f83530..dd04140b 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -33,6 +33,7 @@ import UIKit stack.stackModel?.spacing = 0 addSubview(stack) NSLayoutConstraint.constraintPinSubview(toSuperview: stack) + stack.restack() } open override func updateView(_ size: CGFloat) { @@ -58,18 +59,11 @@ import UIKit open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - - eyebrow.setOptional(with: castModel?.eyebrow, delegateObject, additionalData) - headline.setOptional(with: castModel?.headline, delegateObject, additionalData) - body.setOptional(with: castModel?.body, delegateObject, additionalData) - link.setOptional(with: castModel?.link, delegateObject, additionalData) - - // Hide labels if neeeded. - stack.stackModel?.molecules[0].gone = !eyebrow.hasText - stack.stackModel?.molecules[1].gone = !headline.hasText - stack.stackModel?.molecules[2].gone = !body.hasText - stack.stackModel?.molecules[3].gone = (link.titleLabel?.text?.count ?? 0) == 0 - stack.restack() + stack.updateContainedMolecules(with: [castModel?.eyebrow, + castModel?.headline, + castModel?.body, + castModel?.link], + delegateObject, additionalData) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {