From d54c63b0197c3df058a0e4de5f8a6431b622a61c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 4 Oct 2019 11:39:37 -0400 Subject: [PATCH] beginning to convert the code. --- MVMCoreUI/Atoms/TextFields/TextField.swift | 541 ++++++++++++--------- 1 file changed, 316 insertions(+), 225 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/TextField.swift b/MVMCoreUI/Atoms/TextFields/TextField.swift index 0205b76a..4df53197 100644 --- a/MVMCoreUI/Atoms/TextFields/TextField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextField.swift @@ -6,85 +6,179 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import MVMCoreUI import UIKit -@objc protocol MFTextFieldDelegate: NSObjectProtocol { - // Called when the entered text becomes valid based on the validation block - @objc optional func entryIsValid(_ textfield: MFTextField?) - // Called when the entered text becomes invalid based on the validation block - @objc optional func entryIsInvalid(_ textfield: MFTextField?) - // Dismisses the keyboard. + +@objc protocol TextFieldDelegate: NSObjectProtocol { + /// Called when the entered text becomes valid based on the validation block + @objc optional func entryIsValid(_ textfield: TextField?) + /// Called when the entered text becomes invalid based on the validation block + @objc optional func entryIsInvalid(_ textfield: TextField?) + /// Dismisses the keyboard. @objc optional func dismissFieldInput(_ sender: Any?) } -class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormValidationProtocol { - weak var view: UIView? - @IBOutlet weak var textFieldContainerView: UIView? - @IBOutlet weak var backgroundView: UIView? - @IBOutlet weak var textField: UITextField? - @IBOutlet weak var formLabel: Label? - @IBOutlet weak var separatorView: UIView? - /*make it public so outsider class can know the posistion of it. */ @IBOutlet weak var heightConstraint: NSLayoutConstraint? - @IBOutlet weak var formLabelRightPin: NSLayoutConstraint? - var enabled = false - // To set the placeholder and text +@objcMembers open class TextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormValidationProtocol { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- + + var textFieldContainerView: UIView? + var backgroundView: UIView? + var textField: UITextField? + var formLabel: Label? + var separatorView: UIView? + var view: UIView? + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + weak var text: String? weak var formText: String? weak var fieldKey: String? weak var placeholder: String? - /* will move out in Feb release */ var hideBorder = false - weak var datePicker: UIDatePicker? - private(set) weak var toolbar: UIToolbar? - //helper - var formatter: DateFormatter? // If you're using a MFViewController, you must set this to it weak var uiTextFieldDelegate: UITextFieldDelegate? // The delegate and block for validation. Validates if the text that the user has entered is valid or not. Checked after each change if there is a delegate. weak var mfTextFieldDelegate: MFTextFieldDelegate? + + /*make it public so outsider class can know the posistion of it. */ + + var enabled = false + // To set the placeholder and text + + /* will move out in Feb release */ + var hideBorder = false + + weak var datePicker: UIDatePicker? + private(set) weak var toolbar: UIToolbar? + + //helper + var formatter: DateFormatter? + var valid = false var validationBlock: ((_ enteredValue: String?) -> Bool)? // custom text colors var customEnabledTextColor: UIColor? var customDisabledTextColor: UIColor? + //default error message var errMessage: String? - var editCompleteAction: ((_ text: String?) -> Void)? + var editCompleteAction: ((_ text: String?) -> ())? - - private var customPlaceHolderColor: UIColor? - @IBOutlet private weak var separatorHeightConstraint: NSLayoutConstraint! - private var borderPath: UIBezierPath? - private var calendar: Calendar? - @IBOutlet private weak var textContainerLeftPin: NSLayoutConstraint! - @IBOutlet private weak var errorLableLeftPin: NSLayoutConstraint! - @IBOutlet private weak var formLabelLeftPin: NSLayoutConstraint! - @IBOutlet private weak var textContainerRightPin: NSLayoutConstraint! - @IBOutlet private weak var errorLableRightPin: NSLayoutConstraint! + private var customPlaceHolderColor: UIColor? + private var borderPath: UIBezierPath? + private var calendar: Calendar? + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + + var textContainerLeftPin: NSLayoutConstraint? + var errorLableLeftPin: NSLayoutConstraint? + var formLabelLeftPin: NSLayoutConstraint? + var textContainerRightPin: NSLayoutConstraint? + var errorLableRightPin: NSLayoutConstraint? + var separatorHeightConstraint: NSLayoutConstraint? + var heightConstraint: NSLayoutConstraint? + var formLabelRightPin: NSLayoutConstraint? + + //-------------------------------------------------- + // MARK: - Initializations + //-------------------------------------------------- + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public convenience init() { + self.init(frame: .zero) + } + + /* + public convenience init() { + self.init(frame: .zero) + dropDownCarrotLabel().hidden = false + hasDropDown = false + } + + public convenience init(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { + self.init(frame: .zero) + bothTextFieldDelegates = delegate + } + + public convenience init(withMap map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { + self.init(frame: .zero) + translatesAutoresizingMaskIntoConstraints = false + setWithMap(map, bothDelegates: delegate) + } + + public convenience init(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { + self.init(frame: .zero) + bothTextFieldDelegates = delegate + } + + */ + + class func mfTextField() -> Self? { - // MARK: - setup - func updateView(_ size: CGFloat) { - super.updateView(size) - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.formLabel.updateView(size) - self.label.font = MFStyler.fontForTextFieldUnderLabel() - MFStyler.styleTextField(self.textField) - self.dashLine.updateView(size) - }) - } + let view = self.init() + view?.hasDropDown = false + return view + } - func setupView() { - if !self.view { - backgroundColor = UIColor.clear - let nib = getNib() - let views = nib?.instantiate(withOwner: self, options: nil) + class func mfTextField(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { + + let textField = self.mfTextField() + textField?.bothTextFieldDelegates = delegate + return textField + } + + class func mfTextField(withMap map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { + + let textField = self.mfTextField() + textField?.translatesAutoresizingMaskIntoConstraints = false + textField?.setWithMap(map, bothDelegates: delegate) + return textField + } + + class func mfTextFieldForDropDown() -> Self? { + + let textField = self.mfTextField() + textField?.dropDownCarrotLabel().hidden = false + textField?.hasDropDown = true + return textField + } + + class func mfTextFieldForDropDown(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { + + let textField = self.mfTextFieldForDropDown() + textField?.bothTextFieldDelegates = delegate + return textField + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + override open func setupView() { + + guard subviews.isEmpty else { return } + + translatesAutoresizingMaskIntoConstraints = false + + + backgroundColor = .clear + let view = views?.first as? UIView view?.translatesAutoresizingMaskIntoConstraints = false view?.setContentHuggingPriority(.required, for: .vertical) view?.setContentCompressionResistancePriority(.required, for: .vertical) self.view = view view?.frame = frame + if let view = view { addSubview(view) } @@ -116,54 +210,65 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali textField.smartDashesType = .no textField.smartInsertDeleteType = .no } + } + + func updateView(_ size: CGFloat) { + + super.updateView(size) + DispatchQueue.main.async { [weak self] in + self?.formLabel?.updateView(size) + self?.label.font = MFStyler.fontForTextFieldUnderLabel() + let textField = self?.textField { + MFStyler.styleTextField(textField) + } + self?.dashLine.updateView(size) } } - func getNib() -> UINib? { - return UINib(nibName: NSStringFromClass(type(of: self).self), bundle: MVMCoreUIUtility.bundleForMVMCoreUI()) + deinit { + mfTextFieldDelegate = nil + uiTextFieldDelegate = nil } - class func mfTextField() -> Self? { - let view = self.init() - view?.hasDropDown = false - return view + func draw(_ rect: CGRect) { + super.draw(rect) + borderPath.removeAllPoints() + if !hideBorder { + let frame = textFieldContainerView.frame + borderPath = UIBezierPath() + borderPath.move(to: CGPoint(x: frame.origin.x, y: frame.origin.y + frame.size.height)) + borderPath.addLine(to: CGPoint(x: frame.origin.x, y: frame.origin.y)) + borderPath.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y)) + borderPath.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y + frame.size.height)) + + borderPath?.lineWidth = 1 + + var strokeColor: UIColor? + if errorShowing { + strokeColor = UIColor.mfPumpkin() + } else { + strokeColor = UIColor.mfSilver() + } + + strokeColor?.setStroke() + + borderPath?.stroke() + } } - class func mfTextField(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { - let textField = self.mfTextField() - textField?.bothTextFieldDelegates = delegate - return textField - } - - class func mfTextField(withMap map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { - let textField = self.mfTextField() - textField?.translatesAutoresizingMaskIntoConstraints = false - textField?.setWithMap(map, bothDelegates: delegate) - return textField - } - - class func mfTextFieldForDropDown() -> Self? { - let textField = self.mfTextField() - textField?.dropDownCarrotLabel().hidden = false - textField?.hasDropDown = true - return textField - } - - class func mfTextFieldForDropDown(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { - let textField = self.mfTextFieldForDropDown() - textField?.bothTextFieldDelegates = delegate - return textField - } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- // MARK: - Utilities func createDatePicker() { //tool bar - MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: textField.delegate) + MVMCoreUICommonViewsUtility.addDismissToolbar(textField!, delegate: textField!.delegate) //date picker - datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField) + datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField!) - let calendar = Calendar.current + var calendar = Calendar.current calendar.timeZone = NSTimeZone.system self.calendar = calendar } @@ -172,32 +277,32 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali createDatePicker() if show { if let fromDate = fromDate { - if calendar.isDate(fromDate, inSameDayAs: Date()) { + if (calendar?.isDate(fromDate, inSameDayAs: Date()))! { text = MVMCoreUIUtility.hardcodedString(withKey: "textfield_today_string") } else { self.text = formatter.string(from: fromDate) } } } - datePicker.minimumDate = fromDate - datePicker.maximumDate = toDate + datePicker?.minimumDate = fromDate + datePicker?.maximumDate = toDate } func setDatePickerFrom(_ fromDate: Date?, to toDate: Date?) { if let fromDate = fromDate { - if calendar.isDate(fromDate, inSameDayAs: Date()) { + if (calendar?.isDate(fromDate, inSameDayAs: Date()))! { text = MVMCoreUIUtility.hardcodedString(withKey: "textfield_today_string") } else { self.text = formatter.string(from: fromDate) } } - datePicker.minimumDate = fromDate - datePicker.maximumDate = toDate - datePicker.timeZone = NSTimeZone.system + datePicker?.minimumDate = fromDate + datePicker?.maximumDate = toDate + datePicker?.timeZone = NSTimeZone.system } func dismissDatePicker() -> Date? { - let pickedDate = datePicker.date + let pickedDate = datePicker!.date if let pickedDate = pickedDate { if calendar.isDate(pickedDate, inSameDayAs: Date()) { text = MVMCoreUIUtility.hardcodedString(withKey: "textfield_today_string") @@ -205,49 +310,49 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali self.text = formatter.string(from: pickedDate) } } - textField.resignFirstResponder() + textField?.resignFirstResponder() return pickedDate } func dismissPicker() { - textField.resignFirstResponder() + textField?.resignFirstResponder() } func setErrorMessage(_ errorMessage: String?) { - MVMCoreDispatchUtility.performBlock(onMainThread: { - if self.enabled == true { - self.separatorHeightConstraint.constant = 4 - self.errorShowing = true - self.separatorView.backgroundColor = UIColor.mfPumpkin() - self.label.text() = errorMessage - self.label.numberOfLines = 0 - self.textField.accessibilityValue() = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message"), self.textField.text() ?? "", errorMessage ?? "") - self.setNeedsDisplay() - self.layoutIfNeeded() + DispatchQueue.main.async { [weak self] in + if let enabled = self?.enabled { + self?.separatorHeightConstraint?.constant = 4 + self?.errorShowing = true + self?.separatorView?.backgroundColor = UIColor.mfPumpkin() + self?.label.text() = errorMessage + self?.label.numberOfLines = 0 + self?.textField.accessibilityValue() = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message"), self.textField.text() ?? "", errorMessage ?? "") + self?.setNeedsDisplay() + self?.layoutIfNeeded() } - }) + } } func pushAccessibilityNotification() { - MVMCoreDispatchUtility.performBlock(onMainThread: { - UIAccessibilityPostNotification(UIAccessibility.Notification.layoutChanged, self.textField) - }) + DispatchQueue.main.async { [weak self] in + UIAccessibilityPostNotification(UIAccessibility.Notification.layoutChanged, self?.textField) + } } func hideError() { - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.separatorHeightConstraint.constant = 1 - self.separatorView.backgroundColor = UIColor.black - self.layoutIfNeeded() - self.errorShowing = false - self.label.textColor = UIColor.black - self.label.text() = "" - self.textField.accessibilityValue() = nil - self.setNeedsDisplay() - self.layoutIfNeeded() - }) + DispatchQueue.main.async { [weak self] in + self?.separatorHeightConstraint!.constant = 1 + self?.separatorView?.backgroundColor = UIColor.black + self?.layoutIfNeeded() + self?.errorShowing = false + self?.label.textColor = UIColor.black + self?.label.text() = "" + self?.textField?.accessibilityValue = nil + self?.setNeedsDisplay() + self?.layoutIfNeeded() + } } func placeholder() -> String? { @@ -265,7 +370,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali // fixed crash issue if placeholder != nil { if let color = color { - textField.attributedPlaceholder = NSAttributedString(string: placeholder ?? "", attributes: [ + textField!.attributedPlaceholder = NSAttributedString(string: placeholder ?? "", attributes: [ NSAttributedString.Key.foregroundColor: color ]) } @@ -285,18 +390,18 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali // then only can append regular and picker item if hasDropDown { // MFDLog(@"Label: %@", self.textField.accessibilityLabel); - accessibilityString = accessibilityString ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item")) + accessibilityString = accessibilityString ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item")!) // MFDLog(@"Label: %@", self.textField.accessibilityLabel); } else { - accessibilityString = accessibilityString ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "textfield_regular")) + accessibilityString = accessibilityString ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "textfield_regular")!) // MFDLog(@"Label: %@", self.textField.accessibilityLabel); } - textField.accessibilityLabel() = "\(accessibilityString ?? "") \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state"))" + textField!.accessibilityLabel() = "\(accessibilityString ?? "") \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state"))" } func setFormText(_ formText: String?) { - formLabel.text = formText + formLabel?.text = formText setAccessibilityString(formText) } @@ -305,7 +410,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali } func setText(_ text: String?) { - textField.text = text + textField?.text = text valueChanged() } @@ -326,31 +431,36 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali func setUiTextFieldDelegate(_ uiTextFieldDelegate: UITextFieldDelegate?) { self.uiTextFieldDelegate = uiTextFieldDelegate - textField.delegate = uiTextFieldDelegate + textField?.delegate = uiTextFieldDelegate } func setBothTextFieldDelegates(_ delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { mfTextFieldDelegate = delegate uiTextFieldDelegate = delegate } - - func setWithMap(_ map: [AnyHashable : Any]?) { - if map?.count == 0 { - return - } + + func setWithMap(_ map: [AnyHashable: Any]?) { + + guard let map = map, !map.isEmpty else { return } + + var string = map.string(KeyLabel) - var string = map?.string(KeyLabel) if (string?.count ?? 0) > 0 { formText = string } + string = map?.string(KeyValue) + if (string?.count ?? 0) > 0 { text = string } + string = map?.string(forKey: KeyDisable) + if string?.isEqual(StringY) ?? false || map?.bool(forKey: KeyDisable) != nil { enable(false) } + string = map?.string(KeyErrorMessage) if (string?.count ?? 0) > 0 { errMessage = string @@ -366,12 +476,15 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali if (string == "dropDown") { dropDownCarrotLabel().hidden = false self.hasDropDown = true + } else if (string == "password") { - textField.isSecureTextEntry = true + textField?.isSecureTextEntry = true + } else if (string == "number") { - textField.keyboardType = .numberPad + textField?.keyboardType = .numberPad + } else if (string == "email") { - textField.keyboardType = .emailAddress + textField?.keyboardType = .emailAddress } string = map?.string("regex") @@ -385,7 +498,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali } func setWithMap(_ map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { - MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegate) + MVMCoreUICommonViewsUtility.addDismissToolbar(textField!, delegate: delegate) self.bothTextFieldDelegates = delegate setWithMap(map) } @@ -405,23 +518,23 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali } } - func setLeftPinConstant(_ constant: CGFloat) { - textContainerLeftPin.constant = constant - errorLableLeftPin.constant = constant - formLabelLeftPin.constant = constant + override func setLeftPinConstant(_ constant: CGFloat) { + textContainerLeftPin?.constant = constant + errorLableLeftPin?.constant = constant + formLabelLeftPin?.constant = constant } func setRightPinConstant(_ constant: CGFloat) { - textContainerRightPin.constant = constant - errorLableRightPin.constant = constant - formLabelRightPin.constant = constant + textContainerRightPin?.constant = constant + errorLableRightPin?.constant = constant + formLabelRightPin?.constant = constant } - deinit { - self.bothTextFieldDelegates = nil - } + + //-------------------------------------------------- // MARK: - XIB Helpers + //-------------------------------------------------- func showDropDown(_ show: Bool) { if hasDropDown { dropDownCarrotLabel.hidden = !show @@ -433,47 +546,50 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali func enable(_ enable: Bool) { enabled = enable //Set outside the dispatch so that registerAnimations can know about it - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.isUserInteractionEnabled = enable - self.textField.userInteractionEnabled = enable - self.textField.isEnabled = enable + DispatchQueue.main.async { [weak self] in + self?.isUserInteractionEnabled = enable + self?.textField.userInteractionEnabled = enable + self?.textField.isEnabled = enable if enable { - self.textField.textColor = self.customEnabledTextColor ?? UIColor.black - self.formLabel.textColor = UIColor.mfBattleshipGrey() - self.label.textColor = UIColor.black - if self.errorShowing { - self.separatorView.backgroundColor = UIColor.mfPumpkin() + self?.textField.textColor = self.customEnabledTextColor ?? .black + self?.formLabel.textColor = UIColor.mfBattleshipGrey() + self?.label.textColor = UIColor.black + if self!.errorShowing { + self?.separatorView.backgroundColor = UIColor.mfPumpkin() } else { - self.separatorView.backgroundColor = UIColor.black + self?.separatorView.backgroundColor = .black } - self.showDropDown(true) + self?.showDropDown(true) } else { - self.textField.textColor = self.customDisabledTextColor ?? UIColor.mfSilver() - self.formLabel.textColor = UIColor.mfSilver() - self.label.textColor = UIColor.mfSilver() - self.showDropDown(false) - self.hideError() //should not have error if the field is disabled - self.separatorView.backgroundColor = UIColor.mfSilver() + self?.textField.textColor = self!.customDisabledTextColor ?? UIColor.mfSilver() + self?.formLabel.textColor = UIColor.mfSilver() + self?.label.textColor = UIColor.mfSilver() + self?.showDropDown(false) + self?.hideError() //should not have error if the field is disabled + self?.separatorView.backgroundColor = UIColor.mfSilver() } - }) + } } func showLabel(_ show: Bool) { - label.hidden = !show + label?.hidden = !show } func dashSeperatorView(_ dash: Bool) { if dash { - dashLine.hidden = false + dashLine?.hidden = false //never hide seperator view because it could be possiblely used by other classes for positioning - separatorView.backgroundColor = UIColor.clear + separatorView?.backgroundColor = .clear } else { - dashLine.hidden = true - separatorView.backgroundColor = UIColor.black + dashLine?.hidden = true + separatorView.backgroundColor = .black } } + //-------------------------------------------------- // MARK: - Observing for change + //-------------------------------------------------- + func validateBlock() { valueChanged() } @@ -482,7 +598,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali // update label for placeholder if !errorShowing { - label.text = "" + label?.text = "" } // Check validity. @@ -499,7 +615,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali self.errorMessage = errMessage } if mfTextFieldDelegate.responds(to: #selector(entryIsInvalid(_:))) { - mfTextFieldDelegate.entryIsInvalid(self) + mfTextFieldDelegate?.entryIsInvalid(self) } } else if !previousValidity && valid { hideError() @@ -512,7 +628,7 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali func endInputing() { if isValid { hideError() - separatorView.backgroundColor = UIColor.black + separatorView.backgroundColor = .black } else { if errMessage { self.errorMessage = errMessage @@ -520,12 +636,10 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali } } - // MARK: - helper - func startEditing() { textField.becomeFirstResponder() if !errorShowing { - separatorView.backgroundColor = UIColor.black + separatorView?.backgroundColor = .black separatorHeightConstraint.constant = 1 } } @@ -540,8 +654,9 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali return enabledTextFields } - //#pragma mark - Accessibility - + //-------------------------------------------------- + // MARK: - Accessibility + //-------------------------------------------------- func formatter() -> DateFormatter? { if !formatter { @@ -554,65 +669,41 @@ class MFTextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormVali return formatter } - func draw(_ rect: CGRect) { - super.draw(rect) - borderPath.removeAllPoints() - if !hideBorder { - let frame = textFieldContainerView.frame - borderPath = UIBezierPath() - borderPath.move(to: CGPoint(x: frame.origin.x, y: frame.origin.y + frame.size.height)) - borderPath.addLine(to: CGPoint(x: frame.origin.x, y: frame.origin.y)) - borderPath.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y)) - borderPath.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y + frame.size.height)) + + + //-------------------------------------------------- + // MARK: - Molecular + //-------------------------------------------------- + + override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + if (delegateObject is MVMCoreUIDelegateObject) { + FormValidator.setupValidation(withMolecule: self, delegate: delegateObject?.formValidationProtocol) + let formValidator = FormValidator.getForDelegate(delegateObject?.formValidationProtocol) - borderPath.lineWidth = 1 - - var strokeColor: UIColor? - if errorShowing { - strokeColor = UIColor.mfPumpkin() - } else { - strokeColor = UIColor.mfSilver() - } - - strokeColor?.setStroke() - - borderPath.stroke() + self.withMap = json + mfTextFieldDelegate = formValidator + uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate + MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) } } - ////////////////////// - - #pragma mark - MVMCoreUIMoleculeViewProtocol - - - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { - [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; - FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol]; - - [self setWithMap:json]; - self.mfTextFieldDelegate = formValidator; - self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate; - [MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate]; - } + override open class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 76 } + //-------------------------------------------------- + // MARK: - Form Validation + //-------------------------------------------------- - + (CGFloat)estimatedHeightForRow:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject { - return 76; + public func isValidField() -> Bool { + return isValid } - #pragma mark - FormValidationProtocol - - - - (BOOL)isValidField { - return self.isValid; + public func formFieldName() -> String? { + return fieldKey } - - (nullable NSString *)formFieldName { - return self.fieldKey; - } - - - (nullable id)formFieldValue { - return self.text; + public func formFieldValue() -> Any? { + return text } }