From 72553935c2495efa18aba40dba296c2e854f6bdd Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 22 Nov 2019 12:53:40 -0500 Subject: [PATCH] latestst state. --- MVMCoreUI.xcodeproj/project.pbxproj | 9 +- MVMCoreUI/Atoms/TextFields/DigitBox.swift | 6 +- .../Atoms/TextFields/DigitEntryField.swift | 32 +++--- MVMCoreUI/Atoms/TextFields/EntryField.swift | 99 ++++++------------- .../Atoms/TextFields/MdnEntryField.swift | 18 ++-- .../Atoms/TextFields/TextEntryField.swift | 6 +- ...tainer.swift => EntryFieldContainer.swift} | 14 ++- 7 files changed, 73 insertions(+), 111 deletions(-) rename MVMCoreUI/Containers/views/{FormFieldContainer.swift => EntryFieldContainer.swift} (96%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 64e83406..3cec7248 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -45,7 +45,7 @@ 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; - 0ABD136B237B193A0081388D /* FormFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* FormFieldContainer.swift */; }; + 0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* EntryFieldContainer.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 */; }; @@ -240,7 +240,7 @@ 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = ""; }; 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; - 0ABD136A237B193A0081388D /* FormFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldContainer.swift; sourceTree = ""; }; + 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.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 = ""; }; @@ -451,7 +451,7 @@ 0ABD1369237B18EE0081388D /* views */ = { isa = PBXGroup; children = ( - 0ABD136A237B193A0081388D /* FormFieldContainer.swift */, + 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */, ); path = views; sourceTree = ""; @@ -1139,7 +1139,6 @@ 01509D952327ED1900EF99AA /* HeadlineBodyTextButtonSwitch.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, - D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */, 0A1B4A96233BB18F005B3FB4 /* CheckboxWithLabelView.swift in Sources */, 0A21DB8B235E06EF00C160A2 /* MFDigitTextBox.m in Sources */, D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */, @@ -1209,7 +1208,7 @@ 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, - 0ABD136B237B193A0081388D /* FormFieldContainer.swift in Sources */, + 0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, diff --git a/MVMCoreUI/Atoms/TextFields/DigitBox.swift b/MVMCoreUI/Atoms/TextFields/DigitBox.swift index d590b9e3..d104412a 100644 --- a/MVMCoreUI/Atoms/TextFields/DigitBox.swift +++ b/MVMCoreUI/Atoms/TextFields/DigitBox.swift @@ -9,11 +9,11 @@ import UIKit @objc protocol DigitBoxProtocol { - @objc optional func digitFieldDidDelete(_ textField: UITextField?) + @objc optional func digitFieldDidDelete(_ textField: TextField?) } -@objcMembers open class DigitBox: FormFieldContainer, UITextFieldDelegate, TextFieldDidDeleteProtocol { +@objcMembers open class DigitBox: EntryFieldContainer, UITextFieldDelegate, TextFieldDidDeleteProtocol { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- @@ -29,7 +29,7 @@ import UIKit }() //-------------------------------------------------- - // MARK: - Properties + // MARK: - Stored Properties //-------------------------------------------------- private var previousSize: CGFloat = 0.0 diff --git a/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift index 85a9d812..97728ce0 100644 --- a/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift @@ -57,7 +57,6 @@ import UIKit get { var string = "" digitBoxes.forEach { string += $0.digitField.attributedPlaceholder?.string ?? "" } - return !string.isEmpty ? string : nil } set { @@ -92,7 +91,6 @@ import UIKit get { var string = "" digitBoxes.forEach { string += $0.digitField.text ?? "" } - return string } set { @@ -133,17 +131,21 @@ import UIKit super.init(frame: frame) isAccessibilityElement = false - entryContainer.disableAllBorders = true + entryFieldContainer.disableAllBorders = true } @objc public convenience init() { self.init(frame: .zero) } - @objc public convenience init(numberOfDigits: Int) { + @objc public convenience init(numberOfDigits: Int, secureDigits: Bool = false) { self.init(frame: .zero) self.numberOfDigits = numberOfDigits assembleDigitFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth()) + + if secureDigits { + setAsSecureTextEntry(true) + } } @objc required public init?(coder: NSCoder) { @@ -187,17 +189,17 @@ import UIKit for (index, box) in digitBoxes.enumerated() { accessibleElements.append(box) - entryContainer.addSubview(box) + entryFieldContainer.addSubview(box) - box.topAnchor.constraint(equalTo: entryContainer.topAnchor).isActive = true - entryContainer.bottomAnchor.constraint(equalTo: box.bottomAnchor).isActive = true + box.topAnchor.constraint(equalTo: entryFieldContainer.topAnchor).isActive = true + entryFieldContainer.bottomAnchor.constraint(equalTo: box.bottomAnchor).isActive = true if index == 0 { - box.leadingAnchor.constraint(equalTo: entryContainer.leadingAnchor).isActive = true + box.leadingAnchor.constraint(equalTo: entryFieldContainer.leadingAnchor).isActive = true } else if index == digitBoxes.count - 1 { box.leadingAnchor.constraint(equalTo: prevBox!.trailingAnchor, constant: space).isActive = true - entryContainer.trailingAnchor.constraint(greaterThanOrEqualTo: box.trailingAnchor).isActive = true + entryFieldContainer.trailingAnchor.constraint(greaterThanOrEqualTo: box.trailingAnchor).isActive = true } else { box.leadingAnchor.constraint(equalTo: prevBox!.trailingAnchor, constant: space).isActive = true @@ -217,7 +219,7 @@ import UIKit @objc open override func updateView(_ size: CGFloat) { super.updateView(size) - entryContainer.disableAllBorders = true + entryFieldContainer.disableAllBorders = true DispatchQueue.main.async { [weak self] in guard let self = self else { return } @@ -232,7 +234,7 @@ import UIKit @objc open override func reset() { super.reset() - + resetDigitBoxes() } @@ -315,7 +317,7 @@ import UIKit } } } - + @objc override func startEditing() { selectedDigitBox?.isSelected = true @@ -390,7 +392,7 @@ extension DigitEntryField { return false } - @objc func digitFieldDidDelete(_ textField: UITextField?) { + @objc func digitFieldDidDelete(_ textField: TextField?) { selectPreviousDigitField(textField, clear: true) } @@ -459,6 +461,10 @@ extension DigitEntryField { assembleDigitFieldsView(size: MVMCoreUIUtility.getWidth()) + if let _ = dictionary["secureEntry"] as? Bool { + setAsSecureTextEntry(true) + } + if !dictionary.isEmpty{ for digitBox in digitBoxes { MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: delegateObject as? UITextFieldDelegate) diff --git a/MVMCoreUI/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atoms/TextFields/EntryField.swift index 68c9c20e..5771b300 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryField.swift @@ -26,10 +26,7 @@ import UIKit return label }() - public private(set) var entryContainer: FormFieldContainer = { - let view = FormFieldContainer() - return view - }() + public private(set) var entryFieldContainer = EntryFieldContainer() public private(set) var feedbackLabel: Label = { let label = Label() @@ -57,29 +54,18 @@ import UIKit /// Determines whther the feedback label will clear itself after user interaction or display update. // public var fixedFeedback: Bool = false - private var _isEnabled: Bool = true - private var _showError: Bool = false - private var _isLocked: Bool = false - private var _isSelected: Bool = false - //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- /// Toggles enabled (original) or disabled UI. public var isEnabled: Bool { - get { return _isEnabled } + get { return entryFieldContainer.isEnabled } set (enabled) { - - _isEnabled = enabled - _isLocked = false - _isSelected = false - _showError = false - DispatchQueue.main.async { [weak self] in guard let self = self else { return } - self.entryContainer.isEnabled = enabled + self.entryFieldContainer.isEnabled = enabled self.feedbackLabel.textColor = enabled ? .black : .mfSilver() self.titleLabel.textColor = enabled ? .mfBattleshipGrey() : .mfSilver() } @@ -88,18 +74,12 @@ import UIKit /// Toggles error or original UI. public var showError: Bool { - get { return _showError } + get { return entryFieldContainer.showError } set (error) { - - _showError = error - _isLocked = false - _isSelected = false - _isEnabled = true - DispatchQueue.main.async { [weak self] in guard let self = self else { return } - self.entryContainer.showError = error + self.entryFieldContainer.showError = error self.feedback = error ? self.errorMessage : nil } } @@ -107,44 +87,28 @@ import UIKit /// Toggles original or locked UI. public var isLocked: Bool { - get { return _isLocked } + get { return entryFieldContainer.isLocked } set (locked) { - - _isLocked = locked - _isEnabled = true - _isSelected = false - _showError = false - DispatchQueue.main.async { [weak self] in guard let self = self else { return } - self.entryContainer.isLocked = locked + self.entryFieldContainer.isLocked = locked } } } /// Toggles selected or original (unselected) UI. public var isSelected: Bool { - get { return _isSelected } + get { return entryFieldContainer.isSelected } set (selected) { - - _isSelected = selected - _isLocked = false - _isEnabled = true - _showError = false - DispatchQueue.main.async { [weak self] in guard let self = self else { return } - self.entryContainer.isSelected = selected + self.entryFieldContainer.isSelected = selected } } } - - //-------------------------------------------------- - // MARK: - Computed Properties for Outlets - //-------------------------------------------------- - + /// Sets the text of titleLabel public var title: String? { get { return titleLabel.text } @@ -157,7 +121,7 @@ import UIKit /// Override this to conveniently get/set the textfield(s). public var text: String? { get { return nil } - set { fatalError("You need to override EntryField's 'text' variable in your subclass.") } + set { fatalError("You MUST override EntryField's 'text' variable in your subclass.") } } /// Sets feedback text in the textField. @@ -166,7 +130,7 @@ import UIKit set (newFeedback) { feedbackLabel.text = newFeedback setAccessibilityString(newFeedback) - entryContainer.refreshUI() + entryFieldContainer.refreshUI() } } @@ -174,8 +138,8 @@ import UIKit // MARK: - Constraints //-------------------------------------------------- - public var entryContainerLeading: NSLayoutConstraint? - public var entryContainerTrailing: NSLayoutConstraint? + public var entryFieldContainerLeading: NSLayoutConstraint? + public var entryFieldContainerTrailing: NSLayoutConstraint? public var feedbackLabelTrailing: NSLayoutConstraint? public var feedbackLabelLeading: NSLayoutConstraint? @@ -233,19 +197,19 @@ import UIKit titleLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor) titleLabelLeading?.isActive = true - addSubview(entryContainer) - setupFieldContainerContent(entryContainer) + addSubview(entryFieldContainer) + setupFieldContainerContent(entryFieldContainer) - titleContainerDistance = entryContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4) + titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4) titleContainerDistance?.isActive = true - entryContainerLeading = entryContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) - entryContainerLeading?.isActive = true - entryContainerTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: entryContainer.trailingAnchor) - entryContainerTrailing?.isActive = true + entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) + entryFieldContainerLeading?.isActive = true + entryFieldContainerTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: entryFieldContainer.trailingAnchor) + entryFieldContainerTrailing?.isActive = true addSubview(feedbackLabel) - feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryContainer.bottomAnchor, constant: PaddingOne) + feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: PaddingOne) feedbackContainerDistance?.isActive = true feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) feedbackLabelLeading?.isActive = true @@ -257,11 +221,11 @@ import UIKit @objc open override func layoutSubviews() { super.layoutSubviews() - entryContainer.refreshUI() + entryFieldContainer.refreshUI() } /// Method to override. - /// Intended to add the interactive content (i.e. textField) to the entryContainer. + /// Intended to add the interactive content (i.e. textField) to the entryFieldContainer. @objc open func setupFieldContainerContent(_ container: UIView) { // To be overridden by subclass. } @@ -271,21 +235,16 @@ import UIKit titleLabel.updateView(size) feedbackLabel.updateView(size) - entryContainer.updateView(size) + entryFieldContainer.updateView(size) } @objc open override func reset() { super.reset() - isEnabled = true - _isLocked = false - _isSelected = false - _showError = false - backgroundColor = .clear titleLabel.reset() feedbackLabel.reset() - entryContainer.reset() + entryFieldContainer.reset() titleLabel.textColor = .mfBattleshipGrey() } @@ -295,14 +254,14 @@ import UIKit @objc open override func setLeftPinConstant(_ constant: CGFloat) { - entryContainerLeading?.constant = constant + entryFieldContainerLeading?.constant = constant feedbackLabelLeading?.constant = constant titleLabelLeading?.constant = constant } @objc open override func setRightPinConstant(_ constant: CGFloat) { - entryContainerTrailing?.constant = constant + entryFieldContainerTrailing?.constant = constant feedbackLabelTrailing?.constant = constant titleLabelTrailing?.constant = constant } @@ -317,7 +276,7 @@ extension EntryField { guard let dictionary = json, !dictionary.isEmpty else { return } - entryContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData) + entryFieldContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData) if let titleText = dictionary[KeyTitle] as? String { title = titleText diff --git a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift index 7d279e54..67cdbb9a 100644 --- a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift @@ -29,6 +29,15 @@ import MVMCore /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. private weak var proprietorTextDelegate: UITextFieldDelegate? + /// If you're using a MFViewController, you must set this to it + public override weak var uiTextFieldDelegate: UITextFieldDelegate? { + get { return textField.delegate } + set { + textField.delegate = self + proprietorTextDelegate = newValue + } + } + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -39,15 +48,6 @@ import MVMCore set { text = MVMCoreUIUtility.formatMdn(newValue) } } - /// If you're using a MFViewController, you must set this to it - public override weak var uiTextFieldDelegate: UITextFieldDelegate? { - get { return textField.delegate } - set { - textField.delegate = self - proprietorTextDelegate = newValue - } - } - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 2e7c151b..44cf9572 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -52,7 +52,7 @@ import UIKit get { return super.isEnabled } set (enabled) { super.isEnabled = enabled - + DispatchQueue.main.async { [weak self] in guard let self = self else { return } @@ -201,7 +201,7 @@ import UIKit @objc func dismissFieldInput(_ sender: Any?) { - _ = self.resignFirstResponder() + _ = resignFirstResponder() } public func defaultValidationBlock() { @@ -238,7 +238,7 @@ import UIKit if isValid { showError = false - entryContainer.bottomBar?.backgroundColor = UIColor.black.cgColor + entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor } else if let errMessage = errorMessage { feedback = errMessage diff --git a/MVMCoreUI/Containers/views/FormFieldContainer.swift b/MVMCoreUI/Containers/views/EntryFieldContainer.swift similarity index 96% rename from MVMCoreUI/Containers/views/FormFieldContainer.swift rename to MVMCoreUI/Containers/views/EntryFieldContainer.swift index b890d62b..4300e37d 100644 --- a/MVMCoreUI/Containers/views/FormFieldContainer.swift +++ b/MVMCoreUI/Containers/views/EntryFieldContainer.swift @@ -1,5 +1,5 @@ // -// FormView.swift +// EntryFieldContainer.swift // MVMCoreUI // // Created by Kevin Christiano on 11/12/19. @@ -9,7 +9,7 @@ import UIKit -@objcMembers open class FormFieldContainer: View { +@objcMembers open class EntryFieldContainer: View { //-------------------------------------------------- // MARK: - Drawing Properties //-------------------------------------------------- @@ -101,7 +101,7 @@ import UIKit _isLocked = false _isEnabled = true _showError = false -    + fieldState = selected ? .selected : .original } } @@ -156,8 +156,8 @@ import UIKit super.setupView() isAccessibilityElement = false - isOpaque = false + if let bottomBar = bottomBar { layer.addSublayer(bottomBar) } @@ -185,7 +185,7 @@ import UIKit case locked case disabled - public func setStateUI(for formField: FormFieldContainer) { + public func setStateUI(for formField: EntryFieldContainer) { switch self { case .original: formField.originalUI() @@ -272,8 +272,6 @@ import UIKit guard let dictionary = json, !dictionary.isEmpty else { return } - if let disableAllBorders = dictionary["disableAllBorders"] as? Bool { - self.disableAllBorders = disableAllBorders - } + } }