Further swiftification.

This commit is contained in:
Kevin G Christiano 2019-10-11 13:23:49 -04:00
parent ef2e177b33
commit d4df5745f4

View File

@ -18,7 +18,7 @@ import UIKit
@objc optional func dismissFieldInput(_ sender: Any?) @objc optional func dismissFieldInput(_ sender: Any?)
} }
@objcMembers open class TextField: ViewConstrainingView, MVMCoreUIMoleculeViewProtocol, FormValidationProtocol { @objcMembers open class TextField: ViewConstrainingView {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Outlets // MARK: - Outlets
//-------------------------------------------------- //--------------------------------------------------
@ -30,41 +30,57 @@ import UIKit
var separatorView: UIView? var separatorView: UIView?
var view: UIView? var view: UIView?
/// If you're using a MFViewController, you must set this to it
weak var mfTextFieldDelegate: MFTextFieldDelegate?
// 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.
var uiTextFieldDelegate: UITextFieldDelegate? {
get {
return textField?.delegate
}
set (newValue) {
textField?.delegate = newValue
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
weak var text: String? weak var label: UILabel?
weak var formText: String?
weak var fieldKey: String?
weak var placeholder: String?
// If you're using a MFViewController, you must set this to it //accesories
weak var uiTextFieldDelegate: UITextFieldDelegate? weak var pickerView: UIPickerView?
// 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. */ //utility
var observingForChanges = false
var errorShowing = false
var hasDropDown = false
var dashLine: DashLine?
var dropDownCarrotLabel: UILabel?
var dropDownCarrotWidth: NSLayoutConstraint?
var text: String?
var formText: String?
var fieldKey: String?
var placeholder: String?
var enabled = false var enabled = false
// To set the placeholder and text
/* will move out in Feb release */
var hideBorder = false var hideBorder = false
weak var datePicker: UIDatePicker? weak var datePicker: UIDatePicker?
private(set) weak var toolbar: UIToolbar? private(set) weak var toolbar: UIToolbar?
//helper
var formatter: DateFormatter? var formatter: DateFormatter?
var valid = false var valid = false
var validationBlock: ((_ enteredValue: String?) -> Bool)? var validationBlock: ((_ enteredValue: String?) -> Bool)?
// custom text colors
var customEnabledTextColor: UIColor? var customEnabledTextColor: UIColor?
var customDisabledTextColor: UIColor? var customDisabledTextColor: UIColor?
//default error message
var errMessage: String? var errMessage: String?
var editCompleteAction: ((_ text: String?) -> ())? var editCompleteAction: ((_ text: String?) -> ())?
@ -91,72 +107,47 @@ import UIKit
public override init(frame: CGRect) { public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
}
required public init?(coder: NSCoder) {
super.init(coder: coder)
fatalError("init(coder:) has not been implemented")
} }
public convenience init() { public convenience init() {
self.init(frame: .zero) self.init(frame: .zero)
hasDropDown = false
} }
/* public convenience init(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) {
public convenience init() { self.init(frame: .zero)
self.init(frame: .zero)
dropDownCarrotLabel().hidden = false
hasDropDown = false
}
public convenience init(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { mfTextFieldDelegate = delegate
self.init(frame: .zero) uiTextFieldDelegate = delegate
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? {
let view = self.init()
view?.hasDropDown = false
return view
} }
class func mfTextField(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { public convenience init(withMap map: [AnyHashable: Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) {
self.init(frame: .zero)
let textField = self.mfTextField() setWithMap(map, bothDelegates: delegate)
textField?.bothTextFieldDelegates = delegate
return textField
} }
class func mfTextField(withMap map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? { public convenience init(mfTextFieldForDropDown: Bool) {
self.init(frame: .zero)
let textField = self.mfTextField() dropDownCarrotLabel?.isHidden = false
textField?.translatesAutoresizingMaskIntoConstraints = false hasDropDown = true
textField?.setWithMap(map, bothDelegates: delegate)
return textField
} }
class func mfTextFieldForDropDown() -> Self? { public convenience init(mfTextFieldForDropDownWithMap map: [AnyHashable: Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) {
self.init(frame: .zero)
let textField = self.mfTextField() dropDownCarrotLabel?.isHidden = false
textField?.dropDownCarrotLabel().hidden = false hasDropDown = true
textField?.hasDropDown = true setWithMap(map, bothDelegates: delegate)
return textField
}
class func mfTextFieldForDropDown(withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) -> Self? {
let textField = self.mfTextFieldForDropDown()
textField?.bothTextFieldDelegates = delegate
return textField
} }
//-------------------------------------------------- //--------------------------------------------------
@ -169,59 +160,59 @@ import UIKit
translatesAutoresizingMaskIntoConstraints = false translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .clear
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
let view = views?.first as? UIView if let view = view {
view?.translatesAutoresizingMaskIntoConstraints = false addSubview(view)
view?.setContentHuggingPriority(.required, for: .vertical) }
view?.setContentCompressionResistancePriority(.required, for: .vertical) pinView(toSuperView: view)
self.view = view
view?.frame = frame
if let view = view { textField?.font = MFStyler.fontForTextField()
addSubview(view) translatesAutoresizingMaskIntoConstraints = false
}
pinView(toSuperView: view)
textField.font = MFStyler.fontForTextField() formLabel?.font = MFStyler.fontB3()
translatesAutoresizingMaskIntoConstraints = false formLabel?.textColor = UIColor.mfBattleshipGrey()
formLabel.font = MFStyler.fontB3() label?.font = MFStyler.fontForTextFieldUnderLabel()
formLabel.textColor = UIColor.mfBattleshipGrey() label?.textColor = UIColor.black
label.font = MFStyler.fontForTextFieldUnderLabel() dropDownCarrotLabel?.isHidden = true
label.textColor = UIColor.black separatorView?.backgroundColor = UIColor.black
dashLine?.backgroundColor = UIColor.white
dashLine?.isHidden = true
MFStyler.styleTextField(textField!)
dropDownCarrotLabel.hidden = true dropDownCarrotLabel?.isUserInteractionEnabled = true
separatorView.backgroundColor = UIColor.black let tapOnCarrot = UITapGestureRecognizer(target: self, action: #selector(startEditing))
dashLine.backgroundColor = UIColor.white dropDownCarrotLabel?.addGestureRecognizer(tapOnCarrot)
dashLine.hidden = true enabled = true
MFStyler.styleTextField(textField)
dropDownCarrotLabel.isUserInteractionEnabled = true // Disable SmartQuotes
let tapOnCarrot = UITapGestureRecognizer(target: self, action: #selector(startEditing)) if #available(iOS 11.0, *) {
dropDownCarrotLabel.addGestureRecognizer(tapOnCarrot) textField?.smartQuotesType = .no
enabled = true textField?.smartDashesType = .no
textField?.smartInsertDeleteType = .no
// Disable SmartQuotes }
if #available(iOS 11.0, *) {
textField.smartQuotesType = .no
textField.smartDashesType = .no
textField.smartInsertDeleteType = .no
}
} }
func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
self?.formLabel?.updateView(size) self?.formLabel?.updateView(size)
self?.label.font = MFStyler.fontForTextFieldUnderLabel() self?.label?.font = MFStyler.fontForTextFieldUnderLabel()
let textField = self?.textField { // let textFieldView = {
MFStyler.styleTextField(textField) MFStyler.styleTextField(self!.textField!)
} // }
self?.dashLine.updateView(size) self?.dashLine?.updateView(size)
} }
} }
@ -230,28 +221,23 @@ import UIKit
uiTextFieldDelegate = nil uiTextFieldDelegate = nil
} }
func draw(_ rect: CGRect) { open override func draw(_ rect: CGRect) {
super.draw(rect) 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?.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 borderPath?.lineWidth = 1
var strokeColor: UIColor? let strokeColor = errorShowing ? UIColor.mfPumpkin() : UIColor.mfSilver()
if errorShowing { strokeColor.setStroke()
strokeColor = UIColor.mfPumpkin()
} else {
strokeColor = UIColor.mfSilver()
}
strokeColor?.setStroke()
borderPath?.stroke() borderPath?.stroke()
} }
} }
@ -260,6 +246,14 @@ import UIKit
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
func placeholder() -> String? {
return textField.attributedPlaceholder.string
}
func text() -> String? {
return textField.text()
}
// MARK: - Utilities // MARK: - Utilities
func createDatePicker() { func createDatePicker() {
//tool bar //tool bar
@ -302,12 +296,12 @@ import UIKit
} }
func dismissDatePicker() -> Date? { func dismissDatePicker() -> Date? {
let pickedDate = datePicker!.date var pickedDate = datePicker!.date
if let pickedDate = pickedDate { if let pickedDatei = pickedDate {
if calendar.isDate(pickedDate, inSameDayAs: Date()) { if calendar.isDate(pickedDatei, inSameDayAs: Date()) {
text = MVMCoreUIUtility.hardcodedString(withKey: "textfield_today_string") text = MVMCoreUIUtility.hardcodedString(withKey: "textfield_today_string")
} else { } else {
self.text = formatter.string(from: pickedDate) self.text = formatter.string(from: pickedDatei)
} }
} }
textField?.resignFirstResponder() textField?.resignFirstResponder()
@ -325,9 +319,9 @@ import UIKit
self?.separatorHeightConstraint?.constant = 4 self?.separatorHeightConstraint?.constant = 4
self?.errorShowing = true self?.errorShowing = true
self?.separatorView?.backgroundColor = UIColor.mfPumpkin() self?.separatorView?.backgroundColor = UIColor.mfPumpkin()
self?.label.text() = errorMessage self?.label?.text = errorMessage
self?.label.numberOfLines = 0 self?.label?.numberOfLines = 0
self?.textField.accessibilityValue() = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message"), self.textField.text() ?? "", errorMessage ?? "") self?.textField?.accessibilityValue() = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message"), self.textField.text() ?? "", errorMessage ?? "")
self?.setNeedsDisplay() self?.setNeedsDisplay()
self?.layoutIfNeeded() self?.layoutIfNeeded()
} }
@ -336,7 +330,7 @@ import UIKit
func pushAccessibilityNotification() { func pushAccessibilityNotification() {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
UIAccessibilityPostNotification(UIAccessibility.Notification.layoutChanged, self?.textField) UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: self?.textField)
} }
} }
@ -347,22 +341,14 @@ import UIKit
self?.separatorView?.backgroundColor = UIColor.black self?.separatorView?.backgroundColor = UIColor.black
self?.layoutIfNeeded() self?.layoutIfNeeded()
self?.errorShowing = false self?.errorShowing = false
self?.label.textColor = UIColor.black self?.label?.textColor = UIColor.black
self?.label.text() = "" self?.label?.text = ""
self?.textField?.accessibilityValue = nil self?.textField?.accessibilityValue = nil
self?.setNeedsDisplay() self?.setNeedsDisplay()
self?.layoutIfNeeded() self?.layoutIfNeeded()
} }
} }
func placeholder() -> String? {
return textField.attributedPlaceholder.string
}
func text() -> String? {
return textField.text()
}
// MARK: - Setters // MARK: - Setters
func setPlaceholder(_ placeholder: String?, with color: UIColor?) { func setPlaceholder(_ placeholder: String?, with color: UIColor?) {
@ -375,10 +361,10 @@ import UIKit
]) ])
} }
} }
if textField.text.length > 0 && !errorShowing { if textField?.text.length > 0 && !errorShowing {
label.text = placeholder label?.text = placeholder
} else if !errorShowing { } else if !errorShowing {
label.text = "" label?.text = ""
} }
setAccessibilityString(placeholder) setAccessibilityString(placeholder)
} }
@ -430,7 +416,7 @@ import UIKit
} }
func setUiTextFieldDelegate(_ uiTextFieldDelegate: UITextFieldDelegate?) { func setUiTextFieldDelegate(_ uiTextFieldDelegate: UITextFieldDelegate?) {
self.uiTextFieldDelegate = uiTextFieldDelegate uiTextFieldDelegate = uiTextFieldDelegate
textField?.delegate = uiTextFieldDelegate textField?.delegate = uiTextFieldDelegate
} }
@ -462,19 +448,22 @@ import UIKit
} }
string = map?.string(KeyErrorMessage) string = map?.string(KeyErrorMessage)
if (string?.count ?? 0) > 0 { if (string?.count ?? 0) > 0 {
errMessage = string errMessage = string
} }
// key used to send text value to server // key used to send text value to server
string = map?.string(KeyFieldKey) string = map?.string(KeyFieldKey)
if (string?.count ?? 0) > 0 { if (string?.count ?? 0) > 0 {
fieldKey = string fieldKey = string
} }
string = map?.string(KeyType) string = map?.string(KeyType)
if (string == "dropDown") { if (string == "dropDown") {
dropDownCarrotLabel().hidden = false dropDownCarrotLabel?.isHidden = false
self.hasDropDown = true self.hasDropDown = true
} else if (string == "password") { } else if (string == "password") {
@ -488,6 +477,7 @@ import UIKit
} }
string = map?.string("regex") string = map?.string("regex")
if (string?.count ?? 0) != 0 { if (string?.count ?? 0) != 0 {
validationBlock = { enteredValue in validationBlock = { enteredValue in
return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: string) return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: string)
@ -499,7 +489,8 @@ import UIKit
func setWithMap(_ map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) { func setWithMap(_ map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) {
MVMCoreUICommonViewsUtility.addDismissToolbar(textField!, delegate: delegate) MVMCoreUICommonViewsUtility.addDismissToolbar(textField!, delegate: delegate)
self.bothTextFieldDelegates = delegate uiTextFieldDelegate = delegate
textFieldDelegate = delegate
setWithMap(map) setWithMap(map)
} }
@ -510,35 +501,29 @@ import UIKit
func setDefaultValidationBlock() { func setDefaultValidationBlock() {
self.validationBlock = { enteredValue in self.validationBlock = { enteredValue in
if (enteredValue?.count ?? 0) > 0 { return (enteredValue?.count ?? 0) > 0
return true
} else {
return false
}
} }
} }
override func setLeftPinConstant(_ constant: CGFloat) { open override func setLeftPinConstant(_ constant: CGFloat) {
textContainerLeftPin?.constant = constant textContainerLeftPin?.constant = constant
errorLableLeftPin?.constant = constant errorLableLeftPin?.constant = constant
formLabelLeftPin?.constant = constant formLabelLeftPin?.constant = constant
} }
func setRightPinConstant(_ constant: CGFloat) { open override func setRightPinConstant(_ constant: CGFloat) {
textContainerRightPin?.constant = constant textContainerRightPin?.constant = constant
errorLableRightPin?.constant = constant errorLableRightPin?.constant = constant
formLabelRightPin?.constant = constant formLabelRightPin?.constant = constant
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - XIB Helpers // MARK: - XIB Helpers
//-------------------------------------------------- //--------------------------------------------------
func showDropDown(_ show: Bool) { func showDropDown(_ show: Bool) {
if hasDropDown { if hasDropDown {
dropDownCarrotLabel.hidden = !show dropDownCarrotLabel?.isHidden = !show
dropDownCarrotWidth.active = !show dropDownCarrotWidth?.isActive = !show
setNeedsLayout() setNeedsLayout()
layoutIfNeeded() layoutIfNeeded()
} }
@ -548,41 +533,41 @@ import UIKit
enabled = enable //Set outside the dispatch so that registerAnimations can know about it enabled = enable //Set outside the dispatch so that registerAnimations can know about it
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
self?.isUserInteractionEnabled = enable self?.isUserInteractionEnabled = enable
self?.textField.userInteractionEnabled = enable self?.textField?.isUserInteractionEnabled = enable
self?.textField.isEnabled = enable self?.textField?.isEnabled = enable
if enable { if enable {
self?.textField.textColor = self.customEnabledTextColor ?? .black self?.textField?.textColor = self?.customEnabledTextColor ?? .black
self?.formLabel.textColor = UIColor.mfBattleshipGrey() self?.formLabel?.textColor = UIColor.mfBattleshipGrey()
self?.label.textColor = UIColor.black self?.label?.textColor = UIColor.black
if self!.errorShowing { if self!.errorShowing {
self?.separatorView.backgroundColor = UIColor.mfPumpkin() self?.separatorView?.backgroundColor = UIColor.mfPumpkin()
} else { } else {
self?.separatorView.backgroundColor = .black self?.separatorView?.backgroundColor = .black
} }
self?.showDropDown(true) self?.showDropDown(true)
} else { } else {
self?.textField.textColor = self!.customDisabledTextColor ?? UIColor.mfSilver() self?.textField?.textColor = self!.customDisabledTextColor ?? UIColor.mfSilver()
self?.formLabel.textColor = UIColor.mfSilver() self?.formLabel?.textColor = UIColor.mfSilver()
self?.label.textColor = UIColor.mfSilver() self?.label?.textColor = UIColor.mfSilver()
self?.showDropDown(false) self?.showDropDown(false)
self?.hideError() //should not have error if the field is disabled self?.hideError() //should not have error if the field is disabled
self?.separatorView.backgroundColor = UIColor.mfSilver() self?.separatorView?.backgroundColor = UIColor.mfSilver()
} }
} }
} }
func showLabel(_ show: Bool) { func showLabel(_ show: Bool) {
label?.hidden = !show label?.isHidden = !show
} }
func dashSeperatorView(_ dash: Bool) { func dashSeperatorView(_ dash: Bool) {
if dash { if dash {
dashLine?.hidden = false dashLine?.isHidden = false
//never hide seperator view because it could be possiblely used by other classes for positioning //never hide seperator view because it could be possiblely used by other classes for positioning
separatorView?.backgroundColor = .clear separatorView?.backgroundColor = .clear
} else { } else {
dashLine?.hidden = true dashLine?.isHidden = true
separatorView.backgroundColor = .black separatorView?.backgroundColor = .black
} }
} }
@ -603,7 +588,7 @@ import UIKit
// Check validity. // Check validity.
let previousValidity = valid let previousValidity = valid
if validationBlock { if (validationBlock != nil) {
valid = validationBlock(text) valid = validationBlock(text)
} else { } else {
//if validation not set, input will always be valid //if validation not set, input will always be valid
@ -611,7 +596,7 @@ import UIKit
} }
if previousValidity && !valid { if previousValidity && !valid {
if errMessage { if (errMessage != nil) {
self.errorMessage = errMessage self.errorMessage = errMessage
} }
if mfTextFieldDelegate.responds(to: #selector(entryIsInvalid(_:))) { if mfTextFieldDelegate.responds(to: #selector(entryIsInvalid(_:))) {
@ -653,29 +638,13 @@ import UIKit
} }
return enabledTextFields return enabledTextFields
} }
}
//-------------------------------------------------- // MARK: - Molecular
// MARK: - Accessibility extension TextField {
//--------------------------------------------------
func formatter() -> DateFormatter? { override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
if !formatter {
formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeZone = NSTimeZone.system
formatter.locale = NSLocale.current
formatter.formatterBehavior = .default
}
return formatter
}
//--------------------------------------------------
// MARK: - Molecular
//--------------------------------------------------
override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
if (delegateObject is MVMCoreUIDelegateObject) { if (delegateObject is MVMCoreUIDelegateObject) {
FormValidator.setupValidation(withMolecule: self, delegate: delegateObject?.formValidationProtocol) FormValidator.setupValidation(withMolecule: self, delegate: delegateObject?.formValidationProtocol)
let formValidator = FormValidator.getForDelegate(delegateObject?.formValidationProtocol) let formValidator = FormValidator.getForDelegate(delegateObject?.formValidationProtocol)
@ -683,17 +652,32 @@ import UIKit
self.withMap = json self.withMap = json
mfTextFieldDelegate = formValidator mfTextFieldDelegate = formValidator
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) MVMCoreUICommonViewsUtility.addDismissToolbar(textField!, delegate: uiTextFieldDelegate)
} }
} }
override open class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { override open class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 76 return 76
} }
}
//-------------------------------------------------- // MARK: - Accessibility
// MARK: - Form Validation extension TextField {
//--------------------------------------------------
func formatter() -> DateFormatter? {
if !formatter {
formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeZone = .system
formatter.locale = .current
formatter.formatterBehavior = .default
}
return formatter
}
}
// MARK: - Form Validation
extension TextField: FormValidationProtocol {
public func isValidField() -> Bool { public func isValidField() -> Bool {
return isValid return isValid