beginning to convert the code.
This commit is contained in:
parent
65672b1f04
commit
d54c63b019
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user