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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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 5f17e909217ac125cc3655040c9453963c6c8744 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 20 Apr 2020 18:28:03 -0400 Subject: [PATCH 31/31] 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: